2015-01-21 53 views
0

我一直在做检查什么malloc回报这样的:的malloc的利弊宏包装

void *p; 
p = malloc(100); 
if (p) 
{ 
    perror("malloc"); 
    return false; 
} 

只有一个念头,为什么这样做,如果你能保证让记忆?

#define GET_MEM(p,s,i) do{for(p=NULL,i=0;!(p=calloc(1,s))&&i<5;perror("calloc"),i++)}while(0) 

什么pros和这样的决定cons?应该怎么做?

+0

'做{}而(0)'?! – 2015-01-21 09:06:08

+0

它是从FreeBSD的源代码 – 2015-01-21 09:07:02

+0

免费宏是错了,应该是'如果',而不是(P)'如果(!P)'。也是不必要的,因为你可以做一个'free(NULL)'。 – mch 2015-01-21 09:08:51

回答

2

为什么如果你能保证获得记忆。

你的假设是错误的。

malloc()calloc()realloc()可能会失败。所以当你请求的内存没有被成功分配时,这些函数会重新执行NULL。如果这个检查不存在,那么你继续并开始写入这个未分配的内存位置,这会导致未定义的行为。

如果你的问题是关于为什么在宏中有一个while while循环。下面的链接解释它真的很好

do { ... } while (0) — what is it good for?

1

首先,这是不正确的,实际上做的它应该是什么相反:

void *p; 
p = malloc(100); 
if (p) 
{ 
    perror("malloc"); 
    return false; 
} 

这个if语句说:if(malloc succeeded){ return AN_ERROR; }

应该说:

void *p; 
p = malloc(100); 
if(NULL == p) 
{ 
    perror("malloc"); 
    return false; 
} 

现在至于你的问题:

但有一个想法,为什么如果你可以保证获得记忆?

正如Gopi所说,你不能保证获得记忆。你很可能会耗尽内存,从而无法再分配。您不太可能会耗尽整个过程的所有可用内存,但可能会发生。这就是为什么检查像malloc()calloc()realloc()这样的函数返回是至关重要的。

如果没有足够的内存并且您必须准备好处理这些内存分配函数,则这些内存分配函数都可能失败。让我们假设你的字符串分配空间,但malloc的失败,你不检查的是:

int main(int argc, char *argv[]){ 
    char stringToCopy[] = "Some very long string would be here ..."; 
    char *stringBuffer = malloc(1000); // 1000 char buffer 
    // Malloc failed and we did not check for it 
    strncpy(stringBuffer, stringToCopy); /* UNDEFINED BEHAVIOUR */ 
    return 0; 
} 

所以在这种情况下,malloc的失败,并且我们试图反正字符串复制到缓冲区。一旦我们开始这样做,就会导致未定义的行为。通常这种动作会导致程序因Segmentation Fault而崩溃。

这可能是严重的,可能会导致数据丢失或服务丢失。至少,分段错误会给用户带来不便。

由于一些通用规则:始终检查malloc()calloc()realloc()的返回值; 永不一味地相信这些功能是成功的。

无论你选择做一个宏观的内部此检查与否是你自己的选择(没有很多优势/劣势),但只要确保你进行检查和你正确地执行它。