【问题标题】:Is it required to free a pointer variable before using realloc?在使用 realloc 之前是否需要释放指针变量?
【发布时间】:2012-07-17 22:19:39
【问题描述】:

在再次使用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;
}

【问题讨论】:

    标签: c pointers memory-management malloc


    【解决方案1】:

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

    【讨论】:

    • 谢谢,如果不需要保留myArray指向的数据,哪个选项会更有效?
    • 如果中间的free 是不必要的,那么省略它自然会更有效。
    【解决方案2】:

    一个都没有。您应该始终检查 realloc 是否返回 NULL;如果你不这样做,你就会泄漏内存。此外,您正在转换分配器函数的返回值,即not advisable。此外,您最好使用sizeof(*myArray) 而不是显式的sizeof(type) 构造,因为如果您稍后更改数组/指针的类型,并且您忘记在这里也更改类型,您将面临难以-track-down 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()。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2023-03-24
          • 1970-01-01
          • 1970-01-01
          • 2020-06-01
          • 2017-05-01
          • 1970-01-01
          • 2017-07-29
          • 2021-11-04
          • 1970-01-01
          相关资源
          最近更新 更多