这个帖子,算是解惑了
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[]配对使用吧。