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

时间:2012-03-13 09:03:50

标签: c++ new-operator negative-number bad-alloc

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

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

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

提前致谢!

1 个答案:

答案 0 :(得分:17)

这是我的猜测:

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

假设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可能会在分配器附加元数据后是否会溢出。