许多人建议按照以下方法重新分配内存:
int *temp=realloc(previousVar,newSize);
if(temp==NULL){
printf("errorn");
exit(-1);
}
previousVar=temp;
我理解,如果没有创建新的变量,前一个指针将丢失,因为NULL
将被分配给它。但是,如果程序无论如何都会在失败的情况下退出,那么这些麻烦有什么意义呢?
这是一个堆栈溢出,其中顶部的答案有我所指的:正确使用realloc()
在您提供的示例中,是否将返回值赋给临时对象实际上并不重要。在链接的答案中,作者释放了原始缓冲区,但有人可能会认为这是不必要的,因为进程无论如何都会退出。
但是,考虑下面的例子:
typedef struct
{
int *values;
size_t capacity;
size_t size;
} MyBuffer;
bool append(MyBuffer *buffer, int value)
{
if (buffer->size == buffer->capacity)
{
// No more space, double the buffer.
size_t new_capacity = buffer->capacity * 2;
int *temp = realloc(buffer->values, new_capacity);
if (temp == NULL)
{
return false;
}
buffer->values = temp;
buffer->capacity = new_capacity;
}
buffer->values[buffer->size] = value;
buffer->size++;
return true;
}
函数append
尝试向已分配的缓冲区添加一个新值。如果缓冲区不够大,则尝试使用realloc
来获得更大的缓冲区。如果realloc
失败,函数返回false
。
如果我们将realloc
调用更改为直接设置buffer->values
,我们将在失败的情况下泄漏内存:
buffer->values = realloc(buffer->values, new_capacity);
if (buffer->values == NULL)
{
// Here the original `buffer->values` is lost and we can never access it again.
return false;
}
realloc
不释放原始缓冲区,所以在失败的情况下,我们不再访问它。这是一个问题:在最好的情况下,它是一个内存泄漏,在最坏的情况下,我们可能已经丢失了一些我们仍然需要的数据(在内存泄漏之上)。
所以这取决于你如何处理realloc
失败。如果您记录了一个错误并立即退出,则不需要使用另一个变量来存储结果。如果您在调用链中报告错误,或者您想要进行一些清理,则必须执行此操作。如果您采用第一种方法,那么您需要小心是否重构了这段代码以返回错误而不是退出,因此总是将结果赋值给另一个变量是有一些优点的。