2010-11-21 9 views

Antwort

32

Nein, sollten Sie nicht. Standard 7.20.4.5 sagt:

Die getenv Funktion gibt einen Zeiger auf einen String mit dem Element angepassten Liste zugeordnet. Die Zeichenfolge , auf die verwiesen wird, darf nicht durch das Programm geändert werden, aber möglicherweise durch ein nachfolgender Aufruf der getenv Funktion überschrieben werden.

Ich glaube, dass Löschung durch den Text in Fettschrift abgedeckt ist.

+0

Ja, in der Praxis, wenn ich char * tok = strtok() mit seinem ersten Parameter rufe, ist return von getenv(). Die strlen (tok) und puts (tok) wird nicht funktionieren ... Ein ziemlich verkabeltes Ergebnis, ich glaube es wurde verursacht, weil strtok() durch den Text fett dargestellt wird – ackratos

+1

Etwas veraltet, aber die Linux Man Seiten sagen 'char * getenv()' und nicht 'const char * getenv()'. Ich entdeckte das, weil meine Maschine nicht glücklich darüber war, dass ich die Zeichenkette freigab. Sind die man-Seiten nicht ganz korrekt? Ich hatte immer den Eindruck, wenn eine Funktion einen 'char * zurückgibt. "Man sollte es befreien." – hetepeperfan

+0

@hetepeperfan Es ist nicht nur die man-Seite. Der Funktionsprototyp für 'getenv' gibt tatsächlich' char * 'und nicht' const char * 'zurück. Vielleicht ist die Schnittstelle älter als die übliche Verwendung von' const' oder Vielleicht ist es nur ein Versehen, das zu lange nicht angesprochen wurde. Ich bin damit einverstanden, dass es irreführend ist. – jdolan

7

Sie sollten es nicht freigeben. Dies ist ein Ausschnitt aus der man-Seite:

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

Nicht anfassen!

7

Nein. Sie haben keine Kontrolle über den Speicher. In der Regel handelt es sich um einen Zeiger auf ein statisches Array, das mehrmals wiederverwendet wird. Aus diesem Grund sollten Sie kopieren, wenn Sie planen, es für die spätere Verwendung zu speichern (Sie sollten sicherstellen, dass diese Kopie ordnungsgemäß freigegeben wird).

Wenn die Dokumentation nicht explizit besagt, dass Sie einen Zeiger freigeben dürfen, sollten Sie dies nicht tun.

+0

Ich bin mir im Allgemeinen nicht sicher, aber auf POSIX-Systemen ist es nicht sinnvoll, die Zeichenfolge zu speichern, es sei denn, Ihr Programm ändert die Umgebung. Der Zeiger gab Punkte direkt an die interne Kopie zurück, keinen temporären Puffer. –

+0

@R, es die Dokumente [sagen] (http://www.opengroup.org/onlinepubs/009695399/functions/getenv.html) "Der Rückgabewert von getenv() kann auf statische Daten zeigen, die von nachfolgenden überschrieben werden können ruft nach getenv() [...] ". Es kann sich also ändern, auch wenn es keine Putenv-Aufrufe gibt. –

+0

Diese Sprache wurde in Ausgabe 7 gelöscht, beansprucht jedoch weiterhin, dass die Funktion nicht Thread-sicher ist. Ich nehme an, die einzige streng sanktionierte thread-sichere Art, auf die Umgebung zuzugreifen, ist über 'extern char ** environ;' ... –

4

Sie sollten es nicht löschen. Getenv bekommt nur einen Wert von einem char * Array (char ** environ, wenn ich mich richtig erinnere), das jede Umgebungsvariable enthält. Sie zu löschen führt zu undefiniertem Verhalten.

2

Wahrscheinlich der beste Grund, warum der Standard nicht sagt, dass Sie können. Nur weil eine Funktion einen Zeiger zurückgibt, heißt das nicht, dass der Zeiger gültig ist, um an free zu übergeben. Wenn die Dokumentation einer Funktion nicht explizit angibt, dass die Funktion Speicher wie "durch Aufruf von malloc" zuordnet und einen Zeiger auf diesen Speicher zurückgibt, müssen Sie davon ausgehen, dass der Zeiger nicht gültig ist, um ihn an realloc oder free zu übergeben.