12

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

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

那么为什么new[]在接收到一些巨大的数字时抛出异常,但在接收到最大值时尝试分配size_t呢?1111...1和 和1111...0有什么不一样new[]?:)

提前致谢!

4

1 回答 1

18

这是我的疯狂猜测:

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

假设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

于 2012-03-13T09:21:50.713 回答