我正在试验realloc
,使其大小越来越大,并检查同一块是否被重用:
int main ( void )
{
char * newstr, * prevstr = NULL;
size_t newsize, prevsize = 0;
printf ("We play with reallocn");
while (1) {
newsize = prevsize + 1 + prevsize/3; /* add 33% */
newstr = realloc(prevstr, newsize);
if (newstr == NULL) {
printf ("could not alloc newsize=%zu. Sorryn", newsize);
break;
} else {
printf ("newsize=%zu successfully alloc'edn", newsize);
if (newstr == prevstr) {
printf ("newstr = prevstr:tSame block reusedn");
} else {
printf ("newstr != prevstr:tNew block alloc'edn");
}
prevstr = newstr; prevsize = newsize;
}
}
return (EXIT_SUCCESS);
}
正如预期的那样,最终会达到大小太大并且realloc
无法回答请求的地步。根据手册,realloc
应返回NULL
,并在不成功时设置errno = ENOMEM
。
当我在我的机器上运行上述代码时,情况并非如此,我的机器是一台带有"Darwin Kernel Version 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
这正常吗?读手册页时有什么不明白的地方?
目前这对我的代码来说并不重要,但我可以想象这样的情况:我想测试是否可以在不冒崩溃风险的情况下分配内存。有没有一种标准的方法来测试alloc是否能在不冒崩溃风险的情况下工作?
在谜团解开后添加(见下面的答案):没有崩溃,只是来自malloc的一些系统错误消息阻碍了预期的输出。请参阅以下关于如何避免这种情况的内容
正如注释所述,分配失败时没有崩溃,只有一条错误消息。
如果该消息让您感到恼火,您可以通过将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
操作细节的其他环境变量的描述,请参阅文档。
代码没有崩溃,因为"无法分配newsize=153288611651277。"对不起"输出出现-只打印了一条额外的消息。@Blagovest Buyukliev
附加消息可能是在stderr
而不是stdout
上发送的@Eugene Sh.