在指针变量再次使用realloc
之前是否需要释放内存。以下哪项是正确的?
for(i = 0; i < n; i++){
myArray = (int *)realloc(myArray, i*sizeof(int));
}
for(i = 0; i < n; i++){
myArray = (int *)realloc(myArray, i*sizeof(int));
free(myArray);
myArray = NULL;
}
realloc
的具体用途是在使用它之前不需要free
:它的存在是为了增加已经分配的内存。
因此,这是不必要的,也将是罕见的。当传递NULL
指针时,realloc
的行为与malloc
相同。如果您在调用free
之前使用它,那么您也可以使用malloc
。
这两个例子都不正确,因为您省略了错误处理。所有分配器都可以返回NULL
,而realloc
的使用在这方面有点棘手。仔细阅读文档和示例。具体来说,ptr = realloc(ptr, ...
总是一个坏主意,因为如果realloc
失败并返回NULL
,那么您就丢失了引用并泄露了内存。而是使用tmp变量,例如:
tmp = realloc(ptr, newSize);
if (tmp != NULL)
ptr = tmp;
else handle_error();
两者都没有。您应该始终检查realloc是否返回NULL;如果你不这样做,你就会泄露内存。此外,您正在强制转换分配器函数的返回值,这是不可取的。此外,您最好使用sizeof(*myArray)
而不是显式sizeof(type)
构造,因为如果您稍后更改数组/指针的类型,而忘记在此处更改类型,您将面临难以跟踪segfault和/或内存泄漏错误。综上所述:
for(i = 0; i < n; i++){
int *tmp;
tmp = realloc(myArray, i*sizeof(*myArray));
if (tmp == NULL)
{
free(myArray);
/* And handle error */
}
myArray = tmp;
}
哦,好吧,要真正回答你的问题:你不需要free()。
这取决于您想要做什么。realloc()
专门设计用于接受现有分配并更改其大小,从而保留尽可能多的数据。您提供的两个示例都是正确的,因为它们将进行编译,但它们将做不同的事情。
realloc(NULL, n)
与malloc(n)
相同,因此第二种情况在语义上等价于:
for(i = 0; i < n; i++){
myArray = (int *)malloc(i*sizeof(int));
free(myArray);
myArray = NULL;
}
在第一个示例中,将保留myArray
所指向的数据。在第二个示例中,现有的分配将被丢弃,并替换为全新的、未初始化的分配。原始分配指向的任何数据都将被丢弃。
需要注意的是,如果分配失败,realloc()
将返回NULL
,但如果您向它传递了一个非NULL
指针,则该分配将不会被释放。如果重新分配失败,将一个指针传递到realloc()
并将结果直接分配到同一指针变量中可能会导致内存泄漏,因为原始分配仍然存在。正确的方法是使用临时指针变量。
否。为什么?realloc
的全部意义在于,它重新分配现有的内存块,保留已存储在该内存块中的值。这个想法是,在某些情况下,它可能会重用现有的内存位置,而不是分配一个全新的内存块并复制那里的旧值。
如果您不想保留旧块的内容,那么您可能根本不需要realloc
。
还应该提到的是,在给定适当的参数值的情况下,realloc
的功能还涵盖了malloc
和free
的功能。您在代码的第二个周期中所做的工作实质上是在纯malloc
模式中使用realloc
。