假设有一个函数可以为某些东西接收缓冲区,并且可能需要将内存分配给函数范围内的缓冲区。它可能看起来像这样:
void func_with_buf( ...params..., char** buf ) {
if ( !buf ) {
buf = ( char** )calloc( ... );
}
/* more stuff here */
...
}
现在,稍后在这个函数中有另一个条件语句,其求值为false,如果在if / conditional语句中返回false,则应释放buf
指向指针,因为没有任何东西可以在功能本身中做得更多。
所以,有两种方法,我想知道在可扩展性,重用等方面哪一种被认为是“更安全”和更实用。
方法A)
char* buf;
if ( !func_with_buf( ..., &buf ) ) {
free( buf );
buf = NULL;
/* more error handling here */
}
方法B)
char* buf;
if ( !func_with_buf( ..., &buf ) ) {
/* no need to free buf because func_with_buf handles deallocation internally. */
}
有些东西告诉我,方法 A)将是推荐的方式,但我很好奇,并希望看看我是否已经看过任何东西。
此外,如果程序员需要释放一个指向指针的指针,它是否只是简单地传递给free(p)
并且它会处理它?或者我需要将它转换为相同类型的单个指针吗?
这么多问题......
答案 0 :(得分:4)
我认为两者都是可以接受的,只要它在函数的描述中非常清楚。
就个人而言,如果我有一个分配内存的功能,无论出于何种原因失败,我觉得它有义务释放内存。如果调用者收到错误条件,指示内存无用,则应该预期它也已被释放。
或者换句话说,只有当函数表示成功时,内存才有效。
顺便说一下,在你的功能中你是这样做的:
buf = ( char** )calloc( ... );
但我认为你打算这样做:
*buf = ( char* )calloc( ... );
您要求呼叫者提供您将要修改的指针。所以他们传递了一个指向他们指针的指针,但他们需要的实际数据类型是char
的数组。
关于你的上一个问题(抱歉,我最初没有看到它),不 - 你不需要施放它(除非你想要施放到void*
)。函数free
只占用一个内存地址并释放在那里分配的内存。它不需要类型。
答案 1 :(得分:4)
char* buf = func_with_buf( ..., buf );
以这种方式传入原始buf但返回new或buf,如果出现错误则返回NULL(并在函数中清理)。