处理失败的内存分配

Handling Failed Memory Allocation

这个问题更像是一个完整性检查,而不是 "please solve my problem"。我最近继承了一个应用程序的一些代码,该应用程序由许多具有不同技能的不同开发人员编写了几十年。因此,试图理解代码实际想要做什么本身就是一项使命。

无论如何,我一次又一次地遇到这种动态分配内存的初始化模式,并且很快就检查了结果。因为这段代码同时存在于独立库和 GUI 中,所以之前的开发人员使用 _STANDALONE 宏来检查它并相应地处理错误:

double *myArray = (double *) calloc(length, sizeof(double));
if (myArray == NULL)
 {
      strcat(message1, "myArray");
#ifdef _STANDALONE
      fprintf(stderr, "%s %s\n", message1, message2);
#else
      MessageBox(Window, message1, message2, MB_ICONEXCLAMATION);
#endif
      exit(EXIT_FAILURE);
}

注意:您可以假设 message1message2 包含一个字符串 "failed to allocate memory for varible..." 并且足够大,可以附加额外的 gubbins。

完整性检查来了。内存分配失败的最可能原因是操作系统没有任何备用内存。让我们看一下错误处理代码,如果我们假设没有更多的内存空闲:

简而言之,我建议可以更好地处理这个问题,但正确的路径并不那么明显。

仅仅因为 calloc 失败并不意味着错误处理路径也会失败。

  • calloc 可能因为请求荒谬而失败。例如,如果 length * sizeof (double) 溢出,calloc 应该失败。或者即使没有溢出,请求一开始也是不合理的内存量。在这些情况下,fprintfMessageBox.

  • 可能有足够的可用内存
  • 在不知道 fprintfMessageBox 的实现的情况下,您无法确定它们是否需要额外的内存分配。可能系统已经为他们预留了一些内存,目的是为了在内存不足的情况下显示错误信息。

我不担心 fprintfMessageBox 失败。如果您的系统确实没有足够的空闲内存来处理 fprintfMessageBox,它可能会以其他许多方式崩溃。面对如此极端的内存压力而终止是非常合理的。

这里的大问题是 "length" 的典型大小。如果长度通常非常高(比如 1MB 及以上),可以很安全地假设即使分配失败,您仍然有足够的内存用于简单的消息框。 (检查的实际目标是防止这些非常大的分配)。

如果数组通常很小,最好不要显示任何框。 (您可以做的是预先分配所有必要的资源以显示 window。但不确定消息框是否可行)。

解决这个问题的一种方法是预先分配一些永远不会被使用的内存。

当你 运行 内存不足时,你 free 这个区域,所以希望你的错误处理程序有足够的内存来完成它的工作。