内存分配失败.但为什么会崩溃?或者是吗?

phs*_*phs 21 c malloc memory-management

我正在尝试realloc,给它更大和更大的尺寸,并检查是否重复使用相同的块:

int main ( void )
{
  char * newstr, * prevstr = NULL;
  size_t newsize, prevsize = 0;
  printf ("We play with realloc\n");
  while (1) {
    newsize = prevsize + 1 + prevsize/3; /* add 33% */
    newstr = realloc(prevstr, newsize);
    if (newstr == NULL) {
      printf ("could not alloc newsize=%zu. Sorry\n", newsize);
      break;
    } else {
      printf ("newsize=%zu successfully alloc'ed\n", newsize);
      if (newstr == prevstr) {
        printf ("newstr = prevstr:\tSame block reused\n");
      } else {
        printf ("newstr != prevstr:\tNew block alloc'ed\n");
      }
      prevstr = newstr; prevsize = newsize;
    }
  }
  return (EXIT_SUCCESS);
}
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,最终会达到尺寸过大而realloc无法满足要求的程度.根据手册,realloc应该返回NULL并设置errno = ENOMEM何时不成功.

这不是我在我的机器上运行上述代码时发生的情况,一台带有"Darwin内核版本15.0.0"的Mac.代码崩溃并说,而不是返回NULL

malloc: *** mach_vm_map(size=153288611651584) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
could not alloc newsize=153288611651277. Sorry
Run Code Online (Sandbox Code Playgroud)

这是正常的吗?阅读手册页时我不明白的东西?

这对我目前的代码并不重要,但我可以想象我想测试是否可以分配内存而不会有崩溃的情况.有没有一种标准的方法来测试alloc是否可以正常工作而不会有这样的崩溃风险?

神秘解决后添加(参见下面的答案):没有崩溃,只是来自malloc的一些系统错误消息阻碍了预期的输出.请参阅下文,了解如何避免此问题.

das*_*ght 15

正如评论所述,分配失败没有崩溃,只有错误消息.

如果消息让您烦恼,可以通过重定向malloc日志将其关闭/dev/null,如下所示:

export MallocLogFile=/dev/null
Run Code Online (Sandbox Code Playgroud)

设置环境变量之前的输出如下所示:

newstr = prevstr:   Same block reused
a.out(4275,0x7fff7146e000) malloc: *** mach_vm_map(size=153288611651584) failed (error code=3)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
could not alloc newsize=153288611651277. Sorry
Run Code Online (Sandbox Code Playgroud)

设置变量后,输出如下所示:

newstr = prevstr:   Same block reused
could not alloc newsize=153288611651277. Sorry
Run Code Online (Sandbox Code Playgroud)

注意:这是特定于Mac的.有关调整操作详细信息的其他环境变量的说明,请参阅文档malloc.


chu*_*ica 11

代码没有崩溃,因为"无法分配newsize = 153288611651277.抱歉"输出发生了 - 只是打印了一条额外的消息. @Blagovest Buyukliev

附加消息可能是发送stderr而不是stdout. @Eugene Sh.

  • @phs建议离开.1)这是一个明确的问题.2)它演示了错误消息(`stderr`)混淆正常输出`stdout`的问题.3)我喜欢`realloc()`演示代码为[评论](http://stackoverflow.com/questions/33549070/memory-allocation-fails-but-why-does-it-crash/33549566?noredirect=1 #comment54878525_33549070) (3认同)
  • @phs没有理由删除人们感兴趣的问题(从投票计数中可以看出).你可能想编辑标题而不是谈论`malloc`崩溃,而是谈谈抑制消息. (2认同)
  • @phs - "错误"的问题通常比"正确"的问题更具教育性,因为其他人可能会遇到同样的问题.人们很少发帖说"为什么这与我预期的完全一样",所以看到"为什么这不正常"这样的问题是有用的,即使事实证明它*工作正常,但不是显然是这样. (2认同)