我正在创建一个返回字符串的函数。字符串的大小在运行时是已知的,所以我打算使用 malloc()
,但我不想让用户负责调用 free()
在使用我的函数的返回值之后。
如何实现?返回字符串 (char *
) 的其他函数如何工作(例如 getcwd()
、_getcwd()
、GetLastError()
, SDL_GetError()
)?
最佳答案
您的挑战是某事需要释放资源(即导致free()
发生)。
通常,调用者通过直接调用 free()
(例如,查看 strdup
用户如何工作)或通过调用您提供的函数来释放分配的内存包装免费
。例如,您可能需要调用方调用 foo_destroy
函数。正如另一位发帖人指出的那样,您可能选择将其包装在不透明的 struct
中,尽管这不是必需的,因为拥有自己的分配和销毁函数是即使没有它也很有用(例如用于资源跟踪)。
但是,另一种方法是使用某种形式的清理功能。例如,当分配字符串时,您可以将其附加到池中分配的资源列表,然后在完成后简单地释放池。这就是 apache2
使用其 apr_pool
结构的方式。一般而言,您不会free()
特定于该模型的任何内容。参见 here和(更容易阅读)here .
在 C 语言中不能做的(因为 malloc()
d 结构没有引用计数)是直接确定对象的最后一个“引用”何时超出范围并释放它然后。那是因为你没有引用,你有指针。
最后,您询问了现有函数如何返回 char *
变量:
一些(例如
strdup
、get_current_dir_name
和getcwd
在某些情况下)期望调用者释放。一些(例如在其他情况下的
strerror_r
和getcwd
)期望调用者传入足够大小的缓冲区。有些两者兼而有之:来自
getcwd
手册页:
As an extension to the POSIX.1-2001 standard, Linux (libc4, libc5, glibc)
getcwd()
allocates the buffer dynamically usingmalloc(3)
ifbuf
isNULL
. In this case, the allocated buffer has the lengthsize
unlesssize
is zero, whenbuf
is allocated as big as necessary. The caller shouldfree(3)
the returned buffer.
有些使用内部静态缓冲区,因此不可重入/线程安全(糟糕 - 不要这样做)。查看
strerror
以及发明strerror_r
的原因。有些只返回指向常量的指针(因此可以重入),不需要 free。
有些(如
libxml
)要求您使用单独的free
函数(在本例中为xmlFree()
)有些(如
apr_palloc
)依赖于上面的池技术。
关于c - 返回一个用 malloc 分配的字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22971847/