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

fly*_*hny 12 c++ new-operator bad-alloc negative-number

我尝试bad_alloc通过传递一些否定参数来测试异常new[].当传递小的负数时,我得到了我所希望的 - a bad_alloc.但是,在传递时-1,我可以看到我的对象构造了数千次(我在构造函数中打印静态计数器),应用程序终止于segfault.

new[]转换有符号整数size_t,所以-1是最大size_t-2maximum - 1等.

那么为什么new[]在接收一些巨大的数字时抛出异常,但是在接收到最大值时会尝试分配size_t?是什么区别1111...1,并1111...0new[]?:)

提前致谢!

Mys*_*ial 17

这是我的猜测:

在许多实现中,分配器将在分配的区域旁边放置一些元数据.
(例如,分配的大小.)因此,实际上,您分配的内容超出了您的要求.

我们假设size_t是32位.编译为32位.


当你这样做时:

int *array = new int[-1];
Run Code Online (Sandbox Code Playgroud)

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

4294967292 + 4 bytes = 0 bytes (after overflow)
Run Code Online (Sandbox Code Playgroud)

所以0实际分配了字节.

当您尝试访问内存时,由于您立即超出范围,因此会出现段错误.


现在让我们说你这样做:

int *array = new int[-2];
Run Code Online (Sandbox Code Playgroud)

-2成为-2 * 4 bytes = 4294967288(溢出后).附加4个字节的元数据,你得到4294967288 + 4 = 4294967292.

当分配器4294967292从OS 请求字节时,它被拒绝.所以它抛出bad_alloc.


所以基本上,它可能是-1-2使之间是否分配器附加其元数据后,将溢出的差异.