内存分配失败。但是为什么会崩溃呢?或者是吗?
Memory allocation fails. But why does it crash? Or does it?
我正在试验 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);
}
不出所料,最终达到了大小过大的地步,realloc
无法响应请求。根据手册,realloc
应该returnNULL
,不成功就设置errno = ENOMEM
。
这不是当我在我的机器上 运行 上述代码时发生的情况,一个 Mac 和 "Darwin Kernel Version 15.0.0"。
而不是 returning 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
这正常吗?阅读手册页时我有什么不明白的地方?
目前这对我的代码来说并不重要,但我可以想象我想测试是否可以在不冒崩溃风险的情况下分配内存的情况。有没有标准的方法来测试 alloc 是否可以工作而不会冒这种崩溃的风险?
解开谜团后添加(见下面的答案):没有崩溃,只是来自 malloc 的一些系统错误消息妨碍了预期的输出。请参阅下文了解如何避免这种情况。
代码没有崩溃,因为 "could not alloc newsize=153288611651277. Sorry" 输出发生了 - 只是打印了一条额外的消息。
附加消息可能会在 stderr
而不是 stdout
发出。
如评论所述,分配失败时没有崩溃,只有错误消息。
如果该消息让您感到厌烦,您可以通过将 malloc
的日志重定向到 /dev/null
来关闭它,如下所示:
export MallocLogFile=/dev/null
设置环境变量之前的输出如下所示:
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
设置变量后,输出如下所示:
newstr = prevstr: Same block reused
could not alloc newsize=153288611651277. Sorry
注意: 这是高度 Mac 特定的。有关调整 malloc
操作细节的其他环境变量的描述,请参阅 documentation。
我正在试验 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);
}
不出所料,最终达到了大小过大的地步,realloc
无法响应请求。根据手册,realloc
应该returnNULL
,不成功就设置errno = ENOMEM
。
这不是当我在我的机器上 运行 上述代码时发生的情况,一个 Mac 和 "Darwin Kernel Version 15.0.0"。 而不是 returning 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
这正常吗?阅读手册页时我有什么不明白的地方?
目前这对我的代码来说并不重要,但我可以想象我想测试是否可以在不冒崩溃风险的情况下分配内存的情况。有没有标准的方法来测试 alloc 是否可以工作而不会冒这种崩溃的风险?
解开谜团后添加(见下面的答案):没有崩溃,只是来自 malloc 的一些系统错误消息妨碍了预期的输出。请参阅下文了解如何避免这种情况。
代码没有崩溃,因为 "could not alloc newsize=153288611651277. Sorry" 输出发生了 - 只是打印了一条额外的消息。
附加消息可能会在 stderr
而不是 stdout
发出。
如评论所述,分配失败时没有崩溃,只有错误消息。
如果该消息让您感到厌烦,您可以通过将 malloc
的日志重定向到 /dev/null
来关闭它,如下所示:
export MallocLogFile=/dev/null
设置环境变量之前的输出如下所示:
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
设置变量后,输出如下所示:
newstr = prevstr: Same block reused
could not alloc newsize=153288611651277. Sorry
注意: 这是高度 Mac 特定的。有关调整 malloc
操作细节的其他环境变量的描述,请参阅 documentation。