0

假设一个函数需要一个缓冲区来存放某些东西,并且可能需要将内存分配给函数范围内的缓冲区。它可能看起来像这样:

void func_with_buf( ...params..., char** buf ) {

    if ( !buf ) {
       buf = ( char** )calloc( ... );
    }

    /* more stuff here */
    ...
} 

现在,稍后在这个函数中有另一个条件语句,它的计算结果为假,如果在 if/条件语句中返回假,则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)它会处理它?还是我需要将其转换为相同类型的单个指针?

这么多的问题...

4

2 回答 2

4

我认为两者都是可以接受的,只要在函数的描述中非常清楚。

就个人而言,如果我有一个分配内存的函数并且由于某种原因失败了,我觉得它有义务释放该内存。如果调用者收到指示内存无用的错误条件,他们应该期望它也已被释放。

或者换句话说,内存只有在函数指示成功时才有效。

顺便说一句,在您的功能中,您正在执行以下操作:

buf = ( char** )calloc( ... );

但我认为你打算这样做:

*buf = ( char* )calloc( ... );

您要求调用者提供一个您将修改的指针。所以他们传递了一个指向他们的指针的指针,但他们需要的实际数据类型是一个char.

至于你的最后一个问题(对不起,我一开始没看到),不 - 你不需要投射它(除非你想投射到void*)。该函数free只需要一个内存地址并释放那里分配的任何内存。它不需要类型。

于 2012-09-17T05:09:57.087 回答
4

方法(C)

char* buf = func_with_buf( ..., buf );

这样,您传入原始 buf 但返回新的或 buf,如果出现问题返回 NULL(并在函数中清理)。

于 2012-09-17T05:13:59.523 回答