如果错误,如何检查多个malloc并释放它们?

时间:2014-09-09 21:00:53

标签: c malloc

我有一个程序,我使用很多malloc(和其他类似的函数)来为不同的数据类型分配内存。我们知道这个功能可能会失败。如何编写一个简洁的代码来检查内存是否已成功分配,如果没有,则释放所有以前的malloc,如果有的话?

我想可能会编写一个函数来释放每个指针我malloc,如果它们是!= NULL。但后来我需要发送很多参数。 有更好的想法吗?

感谢。

3 个答案:

答案 0 :(得分:2)

这实际上是一个非平凡的C编码习语问题。一个答案是学习C ++并使用auto_pointer

在C中,我成功地使用了以下习语。

  1. 声明时将所有指针设置为NULL
  2. 仅在需要时分配内存。
  3. 如果分配失败,请在所有指针被释放的末尾设置错误值并goto标签。
  4. 如果由于某种原因需要提前释放指针,请再次将其设置为NULL。
  5. 所有正常执行必须一直到最后才能释放所有内容(没有中间return)。
  6. 最终看起来像这样:

    int err = 0;
    FOO *p = NULL; 
    BAR *q = NULL; 
    BAZ *r = NULL;
    
    p = malloc(...);
    if (!p) {
      err = P_MALLOC_FAILURE;
      goto done;
    }
    ....
    q = malloc(...);
    if (!q) {
      err = Q_MALLOC_FAILURE;
      goto done;
    }
    ....
    // Done with p.  Free it early.
    free(p);
    p = NULL;
    ....
    done:
      free(p);
      free(q);
      return err;
    

    free的定义确保如果指针在结尾处仍为NULL,则不会发生任何事情。如果您不喜欢重复的代码,则可以滥用宏:

    #define ALLOC_OR_FAIL(P) do { \
      P = malloc(sizeof *P); \
      if (!P) { \
        err = P ## _MALLOC_FAILURE; \
        goto done; \
      } } while (0)
    

答案 1 :(得分:0)

好吧,你可以设计你的代码,如果有错误,那么你的程序流就可以回到调用堆栈,所有函数在返回错误条件时释放它们分配的内存。

如果您的代码组织得不好,那么“整齐地”释放所有以前的mallocs的唯一便携方式是,如果您存储了mallocs的全局表,那么每次调用时都要保持最新状态mallocfree(或任何其他分配功能)。

但是,现代操作系统在进程退出时为您释放所有内存,实际上它们可以比您更快地执行此操作,因为它们可以一次性释放整个进程的内存分配。恕我直言,一个实际的决定是在没有明确释放的情况下退出,除非你怀疑你的代码将在一个会泄漏内存的系统上运行。

答案 2 :(得分:0)

就像pzaenger说的那样......

ptr = calloc/malloc/realloc(parameters);

if(ptr == NULL)
{
    printf("Well shucks...");
}

足够简单。

我一直在构建一些代码,目前我也有很多参数7/8,其中大多数是被解除引用的指针等等。

我有一些功能,还有更多功能,使用这些相同的7/8参数。所以为了清理它们,我只是将它们填充到一个结构(c struct)中。这样,我所要做的就是传递一个参数,即struct(或者很可能是一个ptr到struct)。

现在你需要做的就是结构的malloc / calloc内存,然后是结构内任何指针的malloc / calloc内存。

然后你来回传递那个结构,做你需要做的任何事情。

最后,您将浏览结构并释放其中的任何内存malloc / calloc。然后释放内存(如果使用了结构的ptr),用于结构本身。