我正在创建一个返回字符串的函数.字符串的大小在运行时是已知的,所以我打算使用malloc(),但我不想free()在使用函数的返回值后让用户负责调用.
怎么能实现这一目标?如何等功能返回字符串(char *)的工作(如getcwd(),_getcwd(),GetLastError(),SDL_GetError())?
你的挑战是什么需要释放资源(即导致free()发生).
通常,调用者通过free()直接调用(strdup例如,查看用户如何工作)或通过调用您提供包装的函数来释放分配的内存free.例如,您可能需要调用者来调用foo_destroy函数.正如另一张海报所指出的那样,你可能会选择将它包装成不透明的struct,但这并不是必需的,因为拥有自己的分配和销毁功能即使没有它也是有用的(例如用于资源跟踪).
但是,另一种方法是使用某种形式的清理功能.例如,在分配字符串时,您可以将其附加到池中分配的资源列表,然后在完成后立即释放池.这是如何apache2与其apr_pool结构一起工作的.一般来说,你没有free()特别在该模型下的任何东西.见这里和(更易于阅读)在这里.
你不能在C中做什么(因为没有malloc()d结构的引用计数)直接决定了对象的最后一个'引用'何时超出范围然后释放它.那是因为你没有引用,你有指针.
最后,您询问现有函数如何返回char *变量:
有的(如strdup,get_current_dir_name并getcwd在某些情况下)预计主叫释放.
一些(喜欢strerror_r和getcwd在其他情况下)期望调用者传入足够大小的缓冲区.
有些人都这样做:从getcwd手册页:
作为POSIX.1-2001标准的扩展,Linux(libc4,libc5,glibc)
getcwd()使用malloc(3)ifbufis 动态分配缓冲区NULL.在这种情况下,分配的缓冲区具有长度,size除非size为零,何时buf根据需要分配.调用者应该free(3)返回缓冲区.
有些使用内部静态缓冲区,因此不是可重入/线程安全的(哎呀 - 不要这样做).看看strerror和为什么strerror_r被发明.
有些只返回指向常量的指针(所以重入是好的),并且不需要空闲.
有些(像libxml)需要你使用一个单独的free功能(xmlFree()在这种情况下)
有些(比如apr_palloc)依赖于上面的池技术.