C++ 数组在内存中的分配
接前一篇的內(nèi)容,C++中數(shù)組在內(nèi)存中也有靜態(tài)分配和動態(tài)分配的區(qū)別。靜態(tài)數(shù)組建立的方式為:A a[],它在棧上分配空間;動態(tài)方式是使用new,malloc在堆上分配。
數(shù)組要么在靜態(tài)存儲區(qū)被創(chuàng)建(如全局?jǐn)?shù)組),要么在棧或堆上被創(chuàng)建。數(shù)組名對應(yīng)著(而不是指向)一塊內(nèi)存,其地址與容量在生命期內(nèi)保持不變,只有數(shù)組的內(nèi)容可以改變。看下例:
1 #include<iostream> 2 using namespace std; 3 void test() 4 { 5 char ch[]="hello"; 6 ch[0]='H'; 7 char*p="world"; 8 p[0]='W';//出錯 9 cout<<ch<<endl; 10 cout<<p<<endl; 11 } 12 int main() 13 { 14 test(); 15 return 0; 16 } 程序中用指針指向了一個常量字符串"world",C++常量字符串存在常量存儲區(qū),且不能修改,故會出錯。
數(shù)組的在棧上分配,或堆上分配的區(qū)別可以看下例:將test和main函數(shù)修改為下
很明顯程序程序編譯時出現(xiàn):warning C4172: returning address of local variable or temporary。在test調(diào)用結(jié)束后在棧上分配的數(shù)組已經(jīng)銷毀,p即為野指針指向無效內(nèi)容。這里把數(shù)組名作為l函數(shù)返回值。如果換成下面注釋的代碼在堆上分配則沒有問題,注意最后的'\0',字符串的最后是以'\0'來判斷結(jié)束的,不然會出界輸出無效內(nèi)容。這里可以看出C++數(shù)組在內(nèi)存中的存儲形式與上篇內(nèi)容介紹的一樣。將test改為如下:
1 char* test() 2 { 3 char* ch= new char[6];//在堆上 4 ch[0]='h'; 5 ch[1]='e'; 6 ch[2]='l'; 7 ch[3]='l'; 8 ch[4]='0'; 9 ch[5]='\0'; 10 char c[] = "hello world"; 11 char *p = c; 12 cout<< sizeof(c) << endl; // 12字節(jié) 13 cout<< sizeof(ch) << endl; // 4字節(jié) 14 cout<< sizeof(p) << endl; // 4字節(jié) 15 return ch; 16 }靜態(tài)數(shù)組名用sizeof可以知道數(shù)組實際所占的內(nèi)存大小,而指向數(shù)組的指針占用空間即為普通指針的大小。當(dāng)數(shù)組作為函數(shù)的參數(shù)進(jìn)行傳遞時,該數(shù)組自動退化為同類型的指針。
在上一篇關(guān)于C++中類在內(nèi)存中分配的介紹舉例時發(fā)現(xiàn)一個問題,當(dāng)兩個指針指向同一個對象時,發(fā)現(xiàn)delete一個指針銷毀該對象后,用另一個指針扔能調(diào)用該類的函數(shù),這個是野指針應(yīng)該有錯啊。看下面的例子:
1 #include<iostream> 2 using namespace std; 3 class A 4 { 5 public: 6 void fun() 7 { 8 cout<<"class of a:"<<endl; 9 } 10 int num; 11 }; 12 A* test() 13 { 14 A*p; 15 A a; 16 a.num=11; 17 p=&a; 18 p->fun(); 19 return p; 20 } 21 int main() 22 { 23 A*s=test(); 24 s->fun(); 25 return 0; 26 } 程序運(yùn)行結(jié)果:
即兩次輸出class of a,一次是在test函數(shù)內(nèi),一次是s調(diào)用。test內(nèi)的a分配在棧上,函數(shù)結(jié)束后應(yīng)該就銷毀了,為什么s還能調(diào)用fun。原來類中的成員數(shù)據(jù)和函數(shù)是存放在不同位置的。C++類的方法存放在"程序代碼區(qū)",而類中的數(shù)據(jù)成員(對象數(shù)據(jù)成員)存放在類的實例對象中,即該成員數(shù)據(jù)存放在堆或棧中。s指向?qū)ο蟮某蓡T數(shù)據(jù)已銷毀,而類的方法還在。
若將上面代碼第8行改為:cout<<"class of a:"<<this->num<<endl;程序運(yùn)行結(jié)果為:
?
?即s輸出的數(shù)據(jù)成員num為無效,因為該對象已釋放。關(guān)于C++內(nèi)存管理還有很多內(nèi)容,需要進(jìn)一步加強(qiáng)學(xué)習(xí)。
總結(jié)
以上是生活随笔為你收集整理的C++ 数组在内存中的分配的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: doxygen相关问题
- 下一篇: C语言中“指针”和“指针变量”的区别是什