Soll ich char*, das von getenv() zurückgegeben wird, freigeben/löschen?

Lesezeit: 4 Minuten

Benutzeravatar von SunnyShah
SunnyShah

 char * val;                                                                        
 val = getenv("ENV_VAR_NAME");

Oben ist ein Code zum Abrufen der Umgebungsvariablen. Wird es zu einem Speicherleck kommen, wenn ich den von getenv(char*) zurückgegebenen Speicher nicht freigebe? Wenn nein, dann antworten Sie bitte warum?

Nein solltest du nicht. Standard 7.20.4.5 sagt:

Die Funktion getenv gibt einen Zeiger auf eine Zeichenfolge zurück, die dem übereinstimmenden Listenelement zugeordnet ist. Die Zeichenfolge, auf die verwiesen wird, darf vom Programm nicht geändert werdenkann aber durch einen nachfolgenden Aufruf der Funktion getenv überschrieben werden.

Ich glaube, die Löschung wird durch den fett gedruckten Text abgedeckt.

  • Ja, in der Praxis, wenn ich char * tok = strtok() mit seinem ersten Parameter aufrufe, sei die Rückgabe von getenv(). Die strlen(tok) und puts(tok) werden nicht funktionieren … Ein ziemlich verdrahtetes Ergebnis. Ich denke, es wurde durch strtok() verursacht, das durch den fett gedruckten Text abgedeckt wird.

    – ackratos

    1. Juli 2015 um 12:38 Uhr


  • Ein bisschen veraltet, aber die Linux-Manpages sagen char* getenv() und nicht const char* getenv(). Ich habe das entdeckt, weil meine Maschine nicht so glücklich darüber war, dass ich die Saite befreit habe. Sind die Manpages nicht ganz korrekt? Ich hatte immer den Eindruck, wenn eine Funktion a zurückgibt char* man sollte es befreien.?

    – hetepeperfan

    12. Januar 2017 um 9:26 Uhr

  • @hetepeperfan Es ist nicht nur die Manpage. Der Funktionsprototyp für getenv kehrt tatsächlich zurück char * und nicht const char *. Vielleicht ist die Schnittstelle älter als die allgemeine Verwendung von const, oder vielleicht ist es nur ein Versehen, das zu lange nicht angesprochen wurde. Einverstanden, dass es irreführend ist.

    – jdolan

    31. Dezember 2017 um 16:10 Uhr

Benutzeravatar von Nicolas Viennot
Nicolas Viennot

Sie sollten es nicht befreien. Dies ist ein Ausschnitt aus der Manpage:

Wie typischerweise implementiert, gibt getenv() einen Zeiger auf einen String innerhalb der Umgebungsliste zurück. Der Aufrufer muss darauf achten, diese Zeichenfolge nicht zu ändern, da dies die Umgebung des Prozesses ändern würde.

Nicht anfassen!

Nein. Sie haben keine Kontrolle über die Speicherung. Normalerweise ist es ein Zeiger auf ein statisches Array, das mehrfach wiederverwendet wird. Aus diesem Grund Sie sollte Kopieren Sie es, wenn Sie es für die spätere Verwendung speichern möchten (Sie sollten sicherstellen, dass diese Kopie ordnungsgemäß freigegeben wird).

Sofern in der Dokumentation nicht ausdrücklich angegeben ist, dass Sie einen Zeiger freigeben können, sollten Sie dies nicht tun.

  • Ich bin mir im Allgemeinen nicht sicher, aber auf POSIX-Systemen ist es sinnlos, die Zeichenfolge zu speichern, es sei denn, Ihr Programm ändert die Umgebung. Der zurückgegebene Zeiger zeigt direkt auf die interne Kopie, nicht auf einen temporären Puffer.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    21. November 2010 um 12:46 Uhr

  • @R, es sind die Dokumente sagen “Der Rückgabewert von getenv() kann auf statische Daten verweisen, die durch nachfolgende Aufrufe von getenv() überschrieben werden können […]”. Es kann sich also ändern, auch wenn es keine gibt putenv Anrufe.

    – Matthäus Flaschen

    21. November 2010 um 12:58 Uhr

  • Diese Sprache wurde in Ausgabe 7 gelöscht, behauptet aber immer noch, dass die Funktion nicht Thread-sicher ist. Ich nehme an, der einzige streng sanktionierte Thread-sichere Weg, um auf die Umgebung zuzugreifen, ist via extern char **environ;

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    21. November 2010 um 13:48 Uhr

  • @R, danke, ich wusste nicht, dass das nicht die neueste Version ist. Aber es wurde nur aus dem Rückgabewertabschnitt entfernt. Die Beschreibung lautet immer noch: „Die Zeichenfolge, auf die gezeigt wird, kann durch einen nachfolgenden Aufruf von getenv() überschrieben werden. […]”. Ich glaube nicht, dass ich ändere environ ist die Lösung, da es heißt: “Konforme Anwendungen dürfen die Umgebung nicht direkt ändern.” Ich bin mir nicht sicher, warum es immer noch keine gibt getenv_r Anruf.

    – Matthäus Flaschen

    21. November 2010 um 14:04 Uhr

Sie sollten es nicht löschen. Getenv erhält nur einen Wert aus einem char*-Array (char** environ, wenn ich mich richtig erinnere), das alle Umgebungsvariablen enthält. Das Löschen führt zu undefiniertem Verhalten.

Der wahrscheinlich beste Grund dafür ist, dass der Standard nicht sagt, dass Sie es können. Nur weil eine Funktion einen Zeiger zurückgibt, bedeutet dies nicht, dass der Zeiger gültig ist, um an ihn übergeben zu werden free. Es sei denn, die Dokumentation einer Funktion besagt ausdrücklich, dass die Funktion Speicher “wie durch einen Aufruf zuweist malloc” und einen Zeiger auf diesen Speicher zurückgibt, müssen Sie davon ausgehen, dass der Zeiger nicht gültig ist, um dorthin zu gehen realloc oder free.

1393350cookie-checkSoll ich char*, das von getenv() zurückgegeben wird, freigeben/löschen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy