我们应该检查内存分配是否失败?

sas*_*alm 13 c malloc error-handling

我已经看到很多代码在进行分配时检查NULL指针.这使代码变得冗长,如果没有一致地完成,只有当程序员感觉到它时,甚至不能确保程序在地址空间用完时不会崩溃.此外,如果程序无法进行更多分配,那么它无论如何都无法完成其功能,对吧?

所以我的问题是,对于大多数程序来说,根本不检查并且如果内存耗尽会让程序崩溃,这不是更好吗?至少代码更具可读性.

注意

我说的是在现代计算机上运行的桌面应用程序(至少2 GB的地址空间),而且绝对不会运行航天飞机,生命支持系统或BP的石油平台.最重要的是,我在谈论使用malloc但从未真正超过5 MB内存使用量的程序.

Dav*_*ave 11

始终检查返回值,但为了清楚起见,通常包装malloc()一个永不返回的函数NULL:

void *
emalloc(size_t amt){
    void *v = malloc(amt);  
    if(!v){
        fprintf(stderr, "out of mem\n");
        exit(EXIT_FAILURE);
    }
    return v;
}
Run Code Online (Sandbox Code Playgroud)

然后,以后你可以使用

char *foo = emalloc(56);
foo[12] = 'A';
Run Code Online (Sandbox Code Playgroud)

没有内疚.


CB *_*ley 8

是的,你应该从中检查一个空的返回值malloc.即使您无法从内存分配失败中恢复,也应该明确退出.如果内存分配成功继续使应用程序处于不一致状态并且可能导致应该避免的"未定义行为".

例如,您可能最终将不一致的数据写入外部存储,这可能会妨碍下一次运行应用程序的能力.以更加可控的方式快速退出会更安全.

许多想要在分​​配失败时退出的应用程序包含malloc在一个函数中,该函数检查返回值并在失败时显式中止.

可以说,这是C++默认new方法在分配失败时抛出异常的一个优点.它不需要努力退出内存分配失败.

  • @JensGustedt:如果我尝试分配一个大的内存块然后先写入该空间末尾的块,那么当malloc失败时,我最初不会取消引用空指针.如果我不检查`malloc`的返回值,我很可能在导致分段违规之前涂抹其他内存.谁知道会发生什么. (2认同)

小智 7

与Dave的上述方法类似,但添加了一个宏,可以自动将文件名和行号传递给我们的分配例程,以便我们可以在发生故障时报告该信息.

#include <stdio.h>
#include <stdlib.h>

#define ZMALLOC(theSize) zmalloc(__FILE__, __LINE__, theSize)

static void *zmalloc(const char *file, int line, int size)
{
   void *ptr = malloc(size);

   if(!ptr)
   {
      printf("Could not allocate: %d bytes (%s:%d)\n", size, file, line);
      exit(1);
   }

   return(ptr);
}

int main()
{
   /* -- Set 'forceFailure' to a non-zero value in order to observe
         how 'zmalloc' behaves when it cannot allocate the
         requested memory -- */

   int bytes        = 10 * sizeof(int);
   int forceFailure = 0;
   int *anArray     = NULL;

   if(forceFailure)
      bytes = -1;

   anArray = ZMALLOC(bytes);

   free(anArray);

   return(0);
}
Run Code Online (Sandbox Code Playgroud)