我应该释放/删除由getenv()返回的char *吗?

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

上面是获取环境变量的代码,如果我不释放由getenv(char*)返回的内存,是否会导致内存泄漏?如果不会,请解释原因。

5个回答

45
不,你不应该这样做。标准7.20.4.5规定:
“getenv”函数返回指向与匹配列表成员关联的字符串的指针。程序不得修改所指向的字符串,但可能会被后续对“getenv”函数的调用覆盖。
我认为粗体文本中已经包含了删除的内容。

实际上,如果我使用getenv()的返回值作为strtok()的第一个参数来调用char * tok = strtok()。那么strlen(tok)和puts(tok)将无法正常工作...这是一个相当奇怪的结果。我认为这是由于strtok()被粗体文本覆盖所导致的。 - ackratos
1
有点过时,但是Linux man页面上写的是char* getenv()而不是const char* getenv()。我发现这一点是因为我的机器对我释放字符串并不太满意。难道man页面不完全正确吗?我一直以为当一个函数返回一个char*时,应该释放它。 - hetepeperfan
@hetepeperfan 这不仅仅是手册的问题。getenv 函数原型确实返回 char * 而不是 const char *。也许这个接口早于 const 的普及,或者可能只是一个长期未被解决的疏忽。同意它是具有误导性的。 - jdolan

14

不要释放它。这是手册页面的一部分:

通常情况下,getenv() 返回环境列表中的字符串指针。调用者必须注意不要修改这个字符串,因为那样会改变进程的环境。

请勿触碰!


9

不,你不能控制它的存储。通常情况下,它是指向静态数组的指针,该数组会被多次重复使用。因此,如果你计划将其存储以供以后使用,你应该复制它(你应该确保这个副本被正确释放)。

除非文档明确说明可以释放指针,否则你不应该这样做。


1
我不确定一般情况下如何,但在POSIX系统上,除非您的程序修改环境,否则存储字符串没有用处。返回的指针直接指向内部副本,而不是临时缓冲区。 - R.. GitHub STOP HELPING ICE
@R,如果文档中说:“从getenv()返回的值可能指向静态数据,这些数据可能会被后续对getenv()的调用覆盖[...]”,那么即使没有putenv调用,它也可能会发生变化。 - Matthew Flaschen
那种语言在第7版中已被删除,但它仍然声称该函数不是线程安全的。我想唯一严格认可的访问环境的线程安全方式是通过 extern char **environ;... - R.. GitHub STOP HELPING ICE
@R,谢谢,我没有意识到那不是最新版本。但它只是从返回值部分中删除了。描述仍然是这样写的,“指向的字符串可能会被后续对getenv()的调用覆盖[...]”。我不认为修改environ是解决方案,因为它说,“符合要求的应用程序不能直接修改environ。”我不确定为什么还没有getenv_r调用。 - Matthew Flaschen

5

不应该删除它。Getenv只是从一个char*数组(如果我记得正确的话,是char** environ)中获取一个值,该数组包含每个环境变量。删除它们会导致未定义的行为。


2
可能最好的原因是标准没有说明你可以这样做。仅仅因为一个函数返回一个指针并不意味着该指针可以有效地传递给free。除非一个函数的文档明确说明该函数分配内存“就像调用malloc一样”并返回指向该内存的指针,否则您必须假定该指针无效,不能传递给reallocfree

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接