delete和delete[] 的深度思考
2者似乎没有表面上看起来 (一个删除new出来的对象 一个删除对象数组) 那么简单,
他们还有着以下关系 基本类型 和 非基本类型的区别
对于基本数据类型int char 等等 的数组
delete 等效于 delete[]
这似乎听起来很玄乎,和老师教的完全不一样
通常delete[] 用于删除数组 以下代码
、、 auto array = new int[2] ;
- 用Dr memory 检测泄露 8 bytes
- 用_CrtDumpMemoryLeaks() 检测也是8 bytes 宏_CRTDBG_MAP_ALLOC 可以限制具体信息
这结论都是知道的 那么我们来delete 和delete[]
A.对于delete DR memory 没有检测到泄露 只是出现了警告 (invalid heap argument)
_CrtDumpMemoryLeaks() 没有检测到泄露
B.对于delete[] 肯定都没问题的
以下代码就是该文 提出的问题所在
、、 static int count1 = 5; class A { public: int x = count1; ~A() { cout << "~A" << endl; } A() { count1++; } }; int main(int argc, char *argv[]) { auto array = new A[2]; //delete array; _CrtDumpMemoryLeaks(); system("pause"); return 0; }
2个检测泄露方法都显示泄露12 bytes sizeof A显示是4字节,那么多出的四字节是怎么回事呢,结果进一步验证 发现是 记录对象个数 (经过反复测试)的 4字节变量 应该是unsigned int
定位到array的首地址 发现如图信息
intel X86 是小端模式所以地址低到高是 2 5 6 array的地址就是5的地址,可见编译器在实际对象地址之前多分配了4个字节,所以为了保证被分配的内存
全部被归还heap 必须用delete[] 来删除 delete将不会正确删除
断点调试delete[]前后发现 证明了 会删除 256 这3个变量
经验证 release 模式下也是如此
进一步发现 VC 下的文件dbgdel.cpp dbgdel2.cpp 有delete delete[] 等CRT 源码
如果类A不带析构函数 那么久不会出现该问题
结论:
非基本类型的对象数组 删除请用delete[]
基本数据类型的数组删除可用delete和delete[] 为了记忆的一致性 还是最好用delete[]