C++深入淺出講解內(nèi)存四區(qū)與new關(guān)鍵字的使用
寫在前面
從本文開始我就要日常更新C++入門博文啦,從核心編程開始,之前的一些基礎(chǔ)我就不再從零整理了,只有函數(shù)傳參、結(jié)構(gòu)體、指針、數(shù)組等稍微難理解的知識(shí)在之前的博文寫的比較全面;因?yàn)楦偁幋_實(shí)很大,其他人總結(jié)的也很好,要看更詳細(xì)的基礎(chǔ)就看本站的技能樹,非常全面;我寫博客的初衷一是可以記錄自己的學(xué)習(xí),加以鞏固;二是給更多的人更容易的講解來快速入門C++,C/C++永不過時(shí)!??!
內(nèi)存四區(qū)
下文有內(nèi)存四區(qū)的詳細(xì)介紹及作用
內(nèi)存四區(qū)的意義:不同區(qū)域存放的數(shù)據(jù)賦予不同的生命周期,讓我們的編程方式更靈活。
程序運(yùn)行前
在程序編譯后,生成了可執(zhí)行程序.exe,未執(zhí)行程序前分為兩個(gè)區(qū)域?yàn)榇a區(qū)和全局區(qū)
代碼區(qū)
作用:
存放CPU執(zhí)行的機(jī)器指令(二進(jìn)制代碼,由操作系統(tǒng)進(jìn)行管理)
代碼區(qū)是共享的,共享的目的是對于頻繁被執(zhí)行的程序,只需要再內(nèi)存中有一份代碼即可
代碼區(qū)是只讀的,使其只讀的原因是防止程序意外地修改了它的指令
全局區(qū)
全局變量和靜態(tài)常量存放在此
全局區(qū)還包含了常量區(qū),字符串常量和其他常量也存放在此
該區(qū)域的數(shù)據(jù)在程序結(jié)束后由操作系統(tǒng)釋放
代碼示例:
#include<iostream> using namespace std; //全局變量 int g_a = 10; int g_b = 10; const int c_g_a=10; const int c_g_b=10; int main() { //創(chuàng)建普通局部變量 int a = 10; int b = 10; cout << "局部變量a的地址為:" << (int)& a << endl; cout << "局部變量b的地址為:" << (int)& b << endl; int c_l_a = 10; int c_l_b = 10; cout << "局部常量c_l_a的地址為:" << (int)&c_l_a << endl; cout << "局部變量c_l_b的地址為:" << (int)&c_l_b << endl; cout << "全局變量g_a的地址為:" << (int)&g_a << endl; cout << "全局變量g_b的地址為:" << (int)&g_b << endl; //靜態(tài)變量 static int s_a = 10; static int s_b = 10; cout << "靜態(tài)變量s_a的地址為:" << (int)&s_a << endl; cout << "靜態(tài)變量s_b的地址為:" << (int)&s_b << endl; //字符串常量 cout << "字符串常量的地址為:" << (int)&"Hello World" << endl; //const 修飾的變量 //const 修飾的全局變量、const修飾的局部變量 cout << "全局常量c_g_a的地址為:" << (int)&c_g_a << endl; cout << "全局常量c_g_b的地址為:" << (int)&c_g_b << endl; }
各變量地址的關(guān)系:
從運(yùn)行效果可以清楚的看到帶全局的變量地址所占空間相近,而局部的地址相差就比較遠(yuǎn)了,看下我做的圖示總結(jié):
程序運(yùn)行后
棧區(qū)
由編譯器自動(dòng)分配釋放,存放函數(shù)的參數(shù)值,局部變量等
注意事項(xiàng):不要返回局部變量的地址,棧區(qū)開辟的數(shù)據(jù)由編譯器自動(dòng)釋放
#include<iostream> using namespace std; int* func1(int b)//返回值類型為 int *,所以return一個(gè)地址才合法 {//形參數(shù)據(jù)也會(huì)開辟到棧區(qū) b = 100; int a = 10;//局部變量,存放在棧區(qū),棧區(qū)的數(shù)據(jù)在函數(shù)執(zhí)行完成后自動(dòng)釋放 return &a;//返回局部變量的地址 } int main() { //接受func1函數(shù)的返回值 int* p = func1(10); cout << *p << endl;//第一次數(shù)據(jù)正常,因?yàn)榫幾g器會(huì)自動(dòng)保留 cout << *p << endl;//第二次往后是隨機(jī)數(shù),該地址被釋放 cout << *p << endl; }
tips:這里輸出只有一個(gè)10,剩下輸出結(jié)果無法猜測,因?yàn)榉祷氐牡刂芬呀?jīng)被編譯器釋放掉
堆區(qū)
由程序員分配釋放,若程序員不釋放,程序結(jié)束時(shí)由操作系統(tǒng)回收
在C++中主要利用new在棧區(qū)開辟內(nèi)存
示例:
int * func() { //利用new 關(guān)鍵字把棧開辟到堆區(qū) //指針 *p實(shí)質(zhì)上也是棧區(qū)數(shù)據(jù),指針保存的數(shù)據(jù)放到堆區(qū) int* p = new int (10); return p; } int main() { int* a = func(); cout << *a << endl;//無論輸出多少次,都能輸出a的值 cout << *a << endl; cout << *a << endl; }
這里不同于棧區(qū)的時(shí),無論輸出多少次*a,都是結(jié)果十,下面來張圖助理解:
主函數(shù)中用*a作為*p的返回值,a的地址為0x0011,保存的數(shù)據(jù)為10,這是數(shù)據(jù)保存在堆中,除非程序結(jié)束,該地址都不會(huì)被釋放。
new關(guān)鍵字
new的基本語法
開辟:
數(shù)據(jù)類型 + 指針變量 = new +相同數(shù)據(jù)類型 +(賦值)
這樣可在堆區(qū)開辟數(shù)據(jù),作為棧區(qū)函數(shù)返回值也不會(huì)被編譯器自動(dòng)釋放
刪除:
delete 變量地址
堆區(qū)數(shù)據(jù)由管理員開辟或釋放,如果想要釋放數(shù)據(jù)就利用delete關(guān)鍵字
利用new開辟數(shù)組
示例:int* Array = new int[n];
和基本語法相比就是()變成了[],并且里面可以存放常量或者變量,當(dāng)我們想控制數(shù)組長度的時(shí)候,這也是自定義的一種方法。讓 n 等于10,那么數(shù)組Array[]的長度為十,我們可以用隨機(jī)數(shù)來給數(shù)組賦值。釋放數(shù)組也是利用delete關(guān)鍵字,例如 delete[] Array;
刪除數(shù)組加[]放在數(shù)組名前。
例如:
void test02(int *Array) { srand((unsigned int)time(NULL)); for (int i = 0; i < 10; i++) { Array[i] = rand() % 20 + 1; } for (int i = 0; i < 10; i++) { cout << Array[i] << " "; } } int main() { int *Array = new int [10]; test02(Array); }
附帶個(gè)運(yùn)行圖:
到此這篇關(guān)于C++深入淺出講解內(nèi)存四區(qū)與new關(guān)鍵字的使用的文章就介紹到這了,更多相關(guān)C++內(nèi)存四區(qū)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解圖的應(yīng)用(最小生成樹、拓?fù)渑判颉㈥P(guān)鍵路徑、最短路徑)
這篇文章主要介紹了圖的應(yīng)用(最小生成樹、拓?fù)渑判颉㈥P(guān)鍵路徑、最短路徑),需要的朋友可以參考下2015-08-08C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04C++使用鏈表存儲(chǔ)實(shí)現(xiàn)通訊錄功能管理
這篇文章主要為大家詳細(xì)介紹了C++使用鏈表存儲(chǔ)實(shí)現(xiàn)通訊錄功能管理,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06c語言實(shí)現(xiàn)詞頻統(tǒng)計(jì)的簡單實(shí)例
下面小編就為大家?guī)硪黄猚語言實(shí)現(xiàn)詞頻統(tǒng)計(jì)的簡單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09vector與map的erase()函數(shù)詳細(xì)解析
vector和map都不能將it++寫在for循環(huán)中,而在循環(huán)體內(nèi)erase(it)2013-09-09