为什么new[-1]生成segfault,而new[-2]抛出bad_alloc
Why new[-1] generates segfault, while new[-2] throws bad_alloc?
我试图通过向new[]
传递一些负参数来测试bad_alloc
异常。当传递小负数时,我得到了我所希望的——bad_alloc
。然而,当传递-1
时,我可以看到我的对象被构造了数千次(我在构造函数中打印静态计数器),并且应用程序以segfault终止。
new[]
将带符号整数转换为size_t
,因此-1
是size_t
的最大值,-2
是maximum - 1
,依此类推
那么,为什么new[]
在接收到某个巨大的数字时抛出异常,而在接收到size_t
的最大值时尝试分配呢?new[]
的1111...1
和1111...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
有可能决定分配器附加元数据后是否溢出。
相关文章:
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 从构造函数抛出异常时如何克服内存泄漏
- GCC对可能有效的代码抛出init list生存期警告
- new(std::nothrow) int[n] 抛出异常
- new[] / delete[] 并在C++中抛出构造函数/析构函数
- new[] 如果元素默认构造函数可以抛出
- 尽管没有定义标题,但新的抛出bad_alloc <new> ?
- 为什么new[-1]生成segfault,而new[-2]抛出bad_alloc
- 当bad_alloc没有抛出时,“new”没有抛出保证意味着什么
- 如果 Foo 的构造函数抛出,'Foo *p = new Foo()' 中 p 的值是多少?
- new则抛出c++构造函数
- 程序在new抛出bad_alloc之前被终止
- 带nothrow选项的Operator new仍然会抛出异常
- 如果对象的构造函数不是except,可以放置new (expression)抛出
- 当使用new创建其构造函数抛出的对象时,是否泄漏构造对象
- 如何处理c++中new抛出的异常
- C++:抛出异常,是否使用"new"?
- 全局非抛出 ::运算符 new 和 std::malloc 之间的区别
- 如果我自己的构造函数必须在不诉诸"new"的情况下抛出,如何缓解聚合对象构造函数的异常?