C标准库函数中如何判断一个return char指针是否需要空闲?

How to determine whether a return char pointer needs to be free in C standard library functions?

我在C程序开发方面经验不多。如题所述,C标准库函数中如何判断一个return char指针是否需要free?例如,我是否需要释放 stdlib.h 中函数 getenv 和 string.h 中函数 strstr 的 return 指针?我在文档中找不到任何描述。

提前致谢。

在 gnu/linux 中输入 man strstr(或使用您首选的网络搜索引擎进行搜索)。

Manual page for getenv 还指出:

The getenv() function searches the environment list to find the environment variable name, and returns a pointer to the corresponding value string.

此处和 C 中的设计思想通常不是制作任何必要的副本,而是出于性能原因指向已经存在的数据。

一个反例是 strdup,它使用内部 malloc 复制一个字符串,并且必须是 free()d.

每个函数都应在其手册页中注明。

例如getenv() 没有提到删除,而且确实没有必要(或者是错误的)。另一方面,vasprintf() 明确指出返回的指针必须是 free()

http://en.cppreference.com/w/cpp/utility/program/getenv

Modifying the string returned by getenv invokes undefined behavior.

所以你不应该碰那个。

http://en.cppreference.com/w/cpp/string/byte/strstr

Return value: Pointer to the first character of the found substring in str

此 returns 一个指向输入 c 字符串中字符的指针。所以它是指向已经存在的内存的指针,而不是新分配的字符串,你不应该 free 它。

p.s。虽然它没有改变答案,但我从问题的 C++ 标签的角度来看。对于 C 语言文档,请参见手册页,或者对于本网站,http://en.cppreference.com/w/c/program/getenv and http://en.cppreference.com/w/c/string/byte/strstr(与上述内容基本相同)

例如,查看 The Man of getenv 您可以阅读:

Notes

[...] As typically implemented, getenv() returns a pointer to a string within the environment list. The caller must take care not to modify this string , since that would change the environment of the process[...]

强调我的

DESCRIPTION

The getenv() function searches the environment list to find the environment variable name, and returns a pointer to the >corresponding value string.

强调我的

换句话说,您不能释放该指针,因为它是指向进程环境中的字符串的指针,而不是为您的作业分配的字符串。

总是向 free() 呈现 malloc() 和家人向你呈现的东西。

这家人是calloc()realloc()

大多数其他标准库函数不会 return 新分配的内存,也不需要 free()d。 strdup()(如果提供)是例外而不是规则。

fopen() return 这样的函数确实需要交出指针,但 fclose() 而不是 free()

但不幸的是,真正的答案是 'check the documentation and know your libraries'。

C 编码的一个事实是,您几乎完全负责资源管理,包括确切知道交出哪些资源以及何时交出。

这就是 C 的力量和诅咒。万岁,一切尽在掌握!嘘!你做主。

正确设计的库从不 return 您必须手动free() 的指针。如果他们使用动态内存或其他需要清理的资源,他们将有一个用于该目的的函数 - 如果您愿意,您必须手动调用一个析构函数。