我试图弄清楚C ++内存分配机制。我理解operator new()
和new
表达式之间的区别。
但是当我找到here时,operator new()
和operator new[]()
的原型几乎完全相同,operator new[]()
的默认实现应该只调用operator new()
的相应版本1}}。
我的问题是:
operator new()
函数来分配任何大小的内存并将内存用作数组,那么operator new[]()
的目的是什么?我尝试了这段代码:
struct MyClass {
MyClass() { cout << this << "::MyClass()" << endl;}
~MyClass() { cout << this << "::~MyClass()" << endl;}
};
int main()
{
MyClass *ptr = (MyClass *)::operator new[]( sizeof( MyClass) * 3);
new (ptr) MyClass;
new (ptr+1) MyClass;
new (ptr+2) MyClass;
delete[] ptr;
return 0;
}
在崩溃之前打印出以下消息:
0x562ecf758e70::MyClass()
0x562ecf758e71::MyClass()
0x562ecf758e72::MyClass()
0x562ecf758e90::~MyClass()
0x562ecf758e8f::~MyClass()
0x562ecf758e8e::~MyClass()
0x562ecf758e8d::~MyClass()
0x562ecf758e8c::~MyClass()
0x562ecf758e8b::~MyClass()
0x562ecf758e8a::~MyClass()
0x562ecf758e89::~MyClass()
0x562ecf758e88::~MyClass()
0x562ecf758e87::~MyClass()
0x562ecf758e86::~MyClass()
0x562ecf758e85::~MyClass()
0x562ecf758e84::~MyClass()
0x562ecf758e83::~MyClass()
0x562ecf758e82::~MyClass()
0x562ecf758e81::~MyClass()
0x562ecf758e80::~MyClass()
0x562ecf758e7f::~MyClass()
0x562ecf758e7e::~MyClass()
0x562ecf758e7d::~MyClass()
0x562ecf758e7c::~MyClass()
0x562ecf758e7b::~MyClass()
0x562ecf758e7a::~MyClass()
0x562ecf758e79::~MyClass()
0x562ecf758e78::~MyClass()
0x562ecf758e77::~MyClass()
0x562ecf758e76::~MyClass()
0x562ecf758e75::~MyClass()
0x562ecf758e74::~MyClass()
0x562ecf758e73::~MyClass()
0x562ecf758e72::~MyClass()
0x562ecf758e71::~MyClass()
0x562ecf758e70::~MyClass()
*** Error in `/home/alec/.cpp-run/1/a.out': free(): invalid pointer: 0x0000562ecf758e68 ***
为什么delete[]
试图破坏30个不存在且超出operator new[]()
分配的内存的对象?
另外,为什么会崩溃?
答案 0 :(得分:1)
关于问题1)。即使operator new()
和operator new[]()
的默认版本执行相同的操作,程序也可以覆盖operator new[]
并使其行为不同。这是一个定制点。
第2部分)。
标准中有一个脚注
218)
operator new[]
或operator delete[]
直接负责注意重复次数或元素大小 数组。这些操作在数组new
和delete
表达式的其他位置执行。但是,数组new
表达式可以将size
参数增加到operator new[]
以获取存储补充信息的空间。
因此虽然new Myclass[3]
必须将3
存储在某处,以便delete[]
可以找到它,但显然::operator new[]( sizeof( MyClass) * 3)
却没有。至少不在delete[]
期望的地方。
所以似乎delete[]
恰好找到了其他一些数字,并继续销毁不存在的对象,直到它碰到一堵墙。