delete与delete[]以及堆内存分配的一点说明

1. 简述

    本文主要说明两点,第一,对于基本数据类型,delete和delete[]在释放数组上是一样的,至少结果上看是一样的。第二,堆内存地址分配大多数情况是无法预测的,而栈是更容易预测。

2. delete与delete[]   

#include  < iostream >
using   namespace  std;
class  AK {
public :
  AK() { 
    cout 
<<   " make one ak "   <<  endl;
  }
  
~ AK() {
    cout 
<<   " destroy one ak "   <<  endl;
  }
};
int  main() {
    
int   * =   new   int [ 10 ];
    cout 
<<  (size_t)p  <<  endl; // 输出4013520
    delete p;
    // delete []p;
    p 
=   new   int [ 10 ];
    cout 
<<  (size_t)p  <<  endl; // 输出4013520
    delete[] p;
    p 
=   0 ;
    
// -------------------------
    AK 
* pAK  =   new  AK[ 10];        // 输出10次“make one ak”
    cout 
<<  (size_t)pAK  <<  endl; // 输出4013572
    delete pAK;                  // 输出1次“destroy one ak”
    pAK  =   new  AK[ 1000000000 ];    // 输出10次“make one ak”
    cout 
<<  (size_t)pAK  <<  endl; // 输出4013596
    delete []pAK;                // 输出10次“destroy one ak” 

    system( " PAUSE " );
    
return   0 ;
}

      指针p存储在栈中,开辟的空间在堆中,第一次,开辟的空间地址为4013520,用delete释放数组后,第二次,重新开辟,空间地址还是4013520。这说明,delete对于int数组的释放是同样有效的。
     指针pAK存储在栈中,开辟的空间在堆中,第一次开辟的空间地址为 4013572,用delete释放数组后,第二次,重新开辟,空间地址为4013596。说明原来的空间没有完全释放掉,原因就是第一次用delete只调用了一次析构函数,即输出了1次“destroy one ak”。

3. 堆地址的预测难度很大   

#include  < iostream >
using   namespace  std;

int  main() {
    
int * =   new   int ;
    
int * =   new   int ;
    cout 
<<  (size_t)a  <<  endl; // 输出4013416
    cout 
<<  (size_t)b  <<  endl; // 输出4013520
    system(
" PAUSE " );
    
return   0 ;
}

     a,b两个int*存储在栈上,开辟两个int存储在堆中,堆中两个int的地址竟然相差了104个字节。一般如果是栈的话,两个连续定义的int,其地址肯定是连续的。
     原因是堆的实现结构是链表,每次都从链表头开始扫描,找到能够满足需要的内存块就返回,剩余的小块继续放回链表,当有内存释放,再融入链表,因此堆是存在碎片的,而栈是顺序的存储结构,不存在碎片这一说,因此堆中的地址是很难预测的。堆的链表是管理结构,对于动态开辟内存十分适合,不过这也是其地址不好预测的原因之一。一种情况例外,即开辟几个对象,然后把这几个对象都释放掉,再按照相同的顺序开辟相同的对象,对应的地址是相同的。比如:分别开辟int,char,int[10],然后把他们都释放掉,再顺序的开辟int, char, int[10],对应的地址肯定是相同的,因为释放掉以后,链表恢复了原来的情况。

4. 总结

    · 对于基本数据类型数组delete与delete[]一样,对于子定义的类型数组,只有delete[]可以。
    · 堆是一种链表式存储结构,大多数情况下,使用其开辟的数据无法预测。

5. 感慨

    delete,new,delete[],new[]这些操作符,不知道它们究竟是如何具体实现的,因此,很难真的理解为什么delete对基本数据类型数组也是可行,对自定义对象数组是不可行。不过呢,网上的文章看了很多,也没发现有讲出来的,也不纠结了,毕竟,C++很多都是人家隐藏好了,就是为了让你省事,如果不开发驱动级别或者系统级别程序的话,一般还真用不上。
    本文介绍的这些都有一个特点,就是知道这些和不知道这些,对使用没什么大的区别,该new与delete对应还是对应,也没人没事找堆中开辟空间的地址,不过以后再看C++代码的时候,距离真相可能更近了一步,仅此而已。

6. 参考

    delete与delete[]的区别    http://hi.baidu.com/shijg/blog/item/f1b24d16d4b4774920a4e987.html
    C++中delete与delete[]的区别    http://jazka.blog.51cto.com/809003/230220

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值