• 清楚了一点delete和delete[]


    这个帖子,算是解惑了

    http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=311058

    测试环境用的vs2008……

     1 #include "iostream"
     2 using namespace std;
     3 
     4  class Ttest
     5 {
     6 public:
     7      int objcnt;
     8      int descnt;
     9     Ttest();
    10     ~Ttest();
    11 };
    12  Ttest::Ttest()
    13  {
    14          static int objcnt=0;
    15         cout<<"construct: "<<++objcnt<<endl;
    16  }
    17  Ttest::~Ttest()
    18  {
    19      static int descnt=0;
    20         cout<<"dest: "<<++descnt<<endl;
    21  }
    22 void main()
    23 {
    24     int tempvar;
    25     Ttest * p=new Ttest[5];
    26     //delete [] p;
    27     delete p;
    28     cin>>tempvar;
    29 
    30 
    31 }

    用delete[]析构整个数组的元素,用delete,析构首元素。

    接着往下测试,

      发现一个很好玩的现象,若是Ttest * p=new Ttest[5];再delete p;若是在线debug或者生成debug*.exe文件则代码执行到此则卡住了,若是release*.exe文件,则可以运行下去。

    调试的时候能出现内存错误提示。而且debug和release文件夹下的exe执行结果很不一样,

    先贴代码:

     1 #include "iostream"
     2 using namespace std;
     3 
     4 class Ttest
     5 {
     6 public:
     7     int objcnt;
     8     int descnt;
     9     Ttest();
    10     ~Ttest();
    11 };
    12 Ttest::Ttest()
    13 {
    14     static int objcnt=0;
    15     cout<<"construct: "<<++objcnt<<endl;
    16 }
    17 Ttest::~Ttest()
    18 {
    19     static int descnt=0;
    20     cout<<"dest: "<<++descnt<<endl;
    21 }
    22 void main()
    23 {
    24     int tempvar;
    25     Ttest * p=new Ttest[5];
    26     cout<<"pvaraddr: "<<(long)p<<endl;
    27     delete[] p;
    28     Ttest * p2=new Ttest[8];
    29     cout<<"p2varaddr: "<<(long)p2<<endl;
    30     delete[]  p2;
    31     Ttest * p3=new Ttest[3];
    32     cout<<"p3varaddr: "<<(long)p2<<endl;
    33     delete[] p3;
    34 //     delete p;
    35 //     delete (p+1);
    36 
    37     char * testcharp=new char[5];
    38     cout<<"testcharpaddr: "<<(long)testcharp<<endl;
    39     *testcharp='A';
    40     *(testcharp+3)='C';
    41     delete testcharp;
    42 
    43     int* testint2=new int;
    44     * testint2=0x01010101;
    45     cout<<"testint2addr: "<<(long)testint2<<endl;
    46     cout<<"testint2 is: "<<hex<<*testint2<<endl;
    47     //delete testint2;
    48     *(testcharp+2)='C';
    49     cout<<"offset 2 is: "<<*(testcharp+2)<<endl;
    50     *(testcharp+4)='D';
    51     cout<<"offset 4 is: "<<*(testcharp+4)<<endl;
    52 
    53     *(testcharp+5)='E';
    54     cout<<"offset 5 is: "<<*(testcharp+5)<<endl;
    55 
    56     *(testcharp+800)='L';
    57     cout<<"offset 800 is: "<<*(testcharp+800)<<endl;
    58 
    59     cout<<"testint2 is: "<<hex<<*testint2<<endl;
    60 
    61     char * testchar2p=new char;
    62     *testchar2p='f';
    63     cout<<"testchar2paddr: "<<(long)testchar2p<<endl;
    64 
    65     cin>>tempvar;
    66 
    67 
    68 }

    执行结果:

    construct: 1
    construct: 2
    construct: 3
    construct: 4
    construct: 5
    pvaraddr: 3484500
    dest: 1
    dest: 2
    dest: 3
    dest: 4
    dest: 5
    construct: 6
    construct: 7
    construct: 8
    construct: 9
    construct: 10
    construct: 11
    construct: 12
    construct: 13
    p2varaddr: 3484500
    dest: 6
    dest: 7
    dest: 8
    dest: 9
    dest: 10
    dest: 11
    dest: 12
    dest: 13
    construct: 14
    construct: 15
    construct: 16
    p3varaddr: 3484500
    dest: 14
    dest: 15
    dest: 16
    testcharpaddr: 3505088
    testint2addr: 3505088
    testint2 is: 1010101
    offset 2 is: C
    offset 4 is: D
    offset 5 is: E
    offset 800 is: L
    testint2 is: 1430101
    testchar2paddr: 357bd0

    结论:

    1、debug和release还是有区别的,验证了那句话,对一个事物进行观察时,不可能不对它产生影响,大致如此吧。

    2、对于自己生命的对象类型(class),object* pobject=new object[];之后,必须用delete [] pobject;才能调用每个元素的析构函数,并释放所用申请的内存空间。

    若是delete pobject;则只调用首元素的析构,并不能释放所有申请的内存空间(貌似只有首次delete才这样,以后delete也是全部释放了,应该是编译器的事吧)

    对于基本数据类型时,delete 和delete[] 就没区别了。

    3、使用new之后,申请的内存空间之后的一段地址也可以用,这大概是编译器或操作系统做的优化吧。内存这么大,一次给几个字节多麻烦,先给你几百个,需要就自己拿,都用完了再来要,

    有点类似于批发吧。还有对于基本类型和自定义对象类型的,new完之后地址也不连续,大概也是一种优化吧。

    所以还是建议new[]和delete[]配对使用吧。

  • 相关阅读:
    java.util.concurrent学习
    mysql慢查优化总结
    mysql怎么限制某些查询语句的执行?
    数据库操作提交事务如果不关闭,会有什么样的后果?
    apache的500错误是写到哪个文件里面
    apache也可以做负载均衡,跟nignx的区别是什么?
    ajax提交请求为啥url要用这个函数encodeURI
    MySQL性能调优与架构设计读书笔记
    java枚举的作用
    linux的命令
  • 原文地址:https://www.cnblogs.com/zhiying678/p/3190795.html
Copyright © 2020-2023  润新知