6

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;
}
4

4 回答 4

14

的具体用处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();
于 2012-07-18T19:29:17.180 回答
5

没有一个。您应该始终检查 realloc 是否返回 NULL;如果你不这样做,你就会泄漏内存。此外,您正在转换分配器函数的返回值,这是不可取的。此外,您最好使用sizeof(*myArray)而不是显式sizeof(type)构造,因为如果您稍后更改数组/指针的类型,并且您也忘记在此处更改类型,您将面临难以追踪的段错误和/或内存泄漏错误。总结一下:

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()。

于 2012-07-18T19:31:22.333 回答
4

这取决于你想做什么。 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()给并将结果直接分配给同一个指针变量可能会导致内存泄漏,因为原始分配仍然存在。正确的方法是使用临时指针变量。

于 2012-07-18T19:30:02.130 回答
2

没有为什么?的全部意义realloc在于它重新分配了现有的内存块,保留了已经存储在该内存块中的值。这个想法是,在某些情况下,它可能会重用现有的内存位置,而不是分配一个全新的内存块并在那里复制旧值。

如果您不想保留旧块的内容,那么您可能根本不需要realloc

还应该提到的是,在给定适当的参数值的情况下, realloc' 的功能还包括malloc' 和' 的功能。free您在代码的第二个周期中所做的基本上是realloc在纯malloc模式下使用。

于 2012-07-18T19:28:57.810 回答