我无法弄清楚为什么以下在 VS2013 中编译的 C++ 代码会导致崩溃。
#include "stdafx.h"
class A {};
void main()
{
A** arr1 = new A*[5] { new A(), new A(), new A(), new A(), new A() };
delete[] arr1;
A** arr2 = new A*[] { new A(), new A(), new A(), new A(), new A() };
delete[] arr2;
}
第一个数组被正确初始化和删除,但第二个数组在 delete[] arr2
行上导致“%Filename%.exe 已触发断点”异常,后跟调试断言:
File: f:\dd\vctools\crt\crtw32\misc\dbgheap.c
Line: 1322
Expression: _CrtIsValidHeapPointer(pUserData)
这两个数组之间的区别非常明显:一个有明确指定的长度,另一个没有。但是编译器难道不应该足够聪明,可以根据以下初始化列表中的项目数来确定长度吗?因为如果数组由原始对象组成(即 A* arr = new A[] { A(), A(), A() }
),它就可以做到这一点。
请指出我做错了什么或解释这背后的原因。
忽略数组项的内存泄漏。他们在真正的程序中被删除,这个很快就被拼凑起来进行演示。无论哪种方式都会发生崩溃。
最佳答案
为了了解实际情况,我尝试重载 new
和 delete
运算符。我尝试重载 new[]
和 delete[]
但是 VS2013 说它已经在一些 .lib 文件中定义了..所以下面必须做..(请注意,我之前从未重载过 new 或 delete 所以我希望这是正确的)
这是一个 32 位程序,其中 sizeof(int) = 4
。
#include "stdafx.h"
#include <iostream>
void* operator new(std::size_t size) //this is called..
{
std::cout << "Allocated: "<<size<<"\n";
return malloc(size);
}
void operator delete(void* ptr) //this function never gets called.
{
std::cout << "DeAllocated\n";
free(ptr);
}
int main()
{
int** arr1 = new int*[2] {new int(1), new int(2)};
delete[] arr1;
std::cout << "\n\n";
int** arr2 = new int*[] {new int(3), new int(4)};
delete[] arr2;
}
结果是:
Allocated: 8
Allocated: 4
Allocated: 4
Allocated: 0
Allocated: 4
Allocated: 4
那 8 是从哪里来的呢?嗯?
让我们把第一个例子改成:
int** arr1 = new int*[3] {new int(1), new int(2), new int(3)};
第二个:
int** arr2 = new int*[] {new int(4), new int(5), new int(6)};
现在的结果是:
Allocated: 12
Allocated: 4
Allocated: 4
Allocated: 4
Allocated: 0
Allocated: 4
Allocated: 4
Allocated: 4
你看到现在发生了什么吗?第二个似乎分配了错误的大小。换句话说,我认为它说 arr2 的大小为 0 而 arr1 的大小为 12.. 只是猜猜我的结果是什么,哈哈。
关于c++ - 删除没有指定大小的指针数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22107876/