0

我一直在检查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的决定是什么?应该怎么做?

4

2 回答 2

2

如果您可以保证获得内存,为什么要这样做。

你的假设是错误的。

malloc() calloc()并且realloc()可能会失败。因此,当您请求的内存未成功分配时,这些函数将返回 NULL。如果此检查不存在,那么您继续并开始写入此未分配的内存位置,这会导致未定义的行为。

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

do { ... } while (0) — 它有什么用?

于 2015-01-21T09:06:08.863 回答
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();的返回值 永远不要盲目相信这些功能是成功的。

是否选择在宏内部执行此检查是您自己的选择(没有很多优点/缺点),但只需确保执行检查并正确执行即可。

于 2015-01-21T09:43:57.317 回答