为什么new[-1]生成segfault,而new[-2]抛出bad_alloc

Why new[-1] generates segfault, while new[-2] throws bad_alloc?

本文关键字:new 抛出 bad alloc segfault 生成 为什么      更新时间:2023-10-16

我试图通过向new[]传递一些负参数来测试bad_alloc异常。当传递小负数时,我得到了我所希望的——bad_alloc。然而,当传递-1时,我可以看到我的对象被构造了数千次(我在构造函数中打印静态计数器),并且应用程序以segfault终止。

new[]将带符号整数转换为size_t,因此-1size_t的最大值,-2maximum - 1,依此类推

那么,为什么new[]在接收到某个巨大的数字时抛出异常,而在接收到size_t的最大值时尝试分配呢?new[]1111...11111...0之间有什么区别?:)

提前感谢!

这是我的猜测:

在许多实现中,分配器会在分配的区域旁边放置一些元数据
(例如,分配的规模。)所以,实际上,你分配的比你要求的要多。

假设size_t是32位。编译为32位。


当你这样做:

int *array = new int[-1];

-1变为-1 * 4 bytes = 4294967292(在溢出之后)。但是,如果分配器实现将4字节的元数据放在分配的区域旁边。实际大小变为:

4294967292 + 4 bytes = 0 bytes (after overflow)

所以实际上分配了0字节。

当你试图访问内存时,你会出错,因为你会立即出界


现在假设你做到了:

int *array = new int[-2];

-2变为-2 * 4 bytes = 4294967288(在溢出之后)。附加4字节的元数据,得到4294967288 + 4 = 4294967292

当分配器从操作系统请求4294967292字节时,它被拒绝。所以它抛出bad_alloc


因此,基本上,-1-2有可能决定分配器附加元数据后是否溢出。