delete 和 delete[] 的区别

总结一下看的一篇文章

为何new出的对象数组必须要用delete[]删除,而普通数组delete和delete[]都一样

文章中验证了 对象数组 用 delete 删除不行(因为对象数组中还有记录一个元素大小的4个字节字段,delete函数内操作的内存中会有4个字节的偏移,导致数据混乱)

但没有回答普通数组为什么可以用delete 删除

下面是一些总结

1.当 new 一个有析构函数的对象数组的时候 必须要用 delete[]删除

是任何对象数组都必须要用delete[ ]删除么?不是

经过自己的试验,只有 new 有析构函数(不管是程序员显式定义的 还是由编译器创建的nontrival的析构函数《深度探索C++对象模型》,trival的就不算) 的对象的数组才会在内存中占用空间来记录对象个数

所以,普通数组和没有析构函数的对象数组用delete删除就没事。

那么,为什么需要记录有析构函数的对象数组个数呢,就是为了要依次执行析构函数。几个对象就执行几次析构函数。因为析构函数时nontrival的。
而定义 delete [ ] 的原因,就是为了迎合 c++ 的 class 的析构函数的执行。

2.为什么普通数组释放 delete 和 delete[] 都一样 

没有找到delete[] 的具体实现 调试也进不去,猜测下:(以文章中最后的例子为例子)

delete 是默认调用一次析构函数,如果有需要调用的话;
delete[] 是根据 存的数组个数 来决定调用几次析构函数,当然如果没有存对象数组的个数,也就不需要调用析构函数了。

如果是delete p; 
  不管p是什么 都把指针往前移动多少 8*4个字节,在清空内存之前 会先判断某个值是不是对的。---就像对象数组用了delete 就会出现某个值不对,就会出现断言错误


如果是delete[] p;
  判断p是不是有nontrival析构函数的对象数组,
    如果是的话就往前移动 9*4个字节,然后将前8*4个字节当作头,将 (数组元素个数+<yout data>)整个数据当成 pUserData,然后再进行析构函数的调用 和 一次性释放内存。
    如果不是的话,就调用delete p;----(猜测)这就是普通数组释放内存的情况。’

 这些本质上都是在new的时候分配的内存结构有关。

3.如果new[]不需要记录对象大小,而是用pHead中的nDataSize来推算会怎么样

文章中有pHead中的nDataSize成员,记录了元素大小 ,从而可以推出元素个数:

元素对象个数 = pHead->nDataSize / sizeof(T) 

但是事实上,new / malloc 在分配内存的时候会 round up 到某个数的倍数(8 或 16 等,跟 malloc 具体实现有关)。也就是说nDataSize并不是等于 sizeof(T)*个数(会大于等于这个数)。根据这样来推算,就有可能多调用析构函数。

猜你喜欢

转载自blog.csdn.net/u012138730/article/details/89679756