您好,登錄后才能下訂單哦!
這篇文章主要講解了“C++內(nèi)存四區(qū)是什么”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“C++內(nèi)存四區(qū)是什么”吧!
C++ 在程序執(zhí)行時,將內(nèi)存大致分為代碼區(qū),全局區(qū),棧區(qū)和堆區(qū)四個區(qū)域。不同的區(qū)域存儲不同的數(shù)據(jù),賦予不同的生命周期,能夠更靈活地進行編程。
代碼區(qū):存放函數(shù)體的二進制代碼,由操作系統(tǒng)管理創(chuàng)建,代碼區(qū)時共享的,對于頻繁被執(zhí)行的程序,只需要存有一份代碼即可;
全局區(qū):存放全局變量和靜態(tài)變量以及常量,在程序結(jié)束后由操作系統(tǒng)釋放;
棧區(qū):由編譯其自動分配釋放,存放函數(shù)的參數(shù)值以及局部變量等;
堆區(qū):一般由程序員通過 new 開辟空間,進行分配和釋放,若程序員不釋放,則程序結(jié)束時由操作系統(tǒng)回收
下面通過一個例子對全局區(qū),棧區(qū),堆區(qū)的數(shù)據(jù)聲明周期進行說明:
// 全局變量屬于全局區(qū),由操作系統(tǒng)管理釋放 int g_a = 1; int g_b = 2; int main(void) { cout << "g_a 的地址為: "<< int(&g_a) << endl; cout << "g_b 的地址為: " << int(&g_b) << endl; // 創(chuàng)建普通的局部變量,屬于棧區(qū) int a = 10; int b = 20; cout << "a 的地址為: " << int(&a) << endl; cout << "b 的地址為: " << int(&b) << endl; // 創(chuàng)建靜態(tài)變量,屬于全局區(qū) static int s_a = 40; static int s_b = 50; cout << "s_a 的地址為: " << int(&s_a) << endl; cout << "s_b 的地址為: " << int(&s_b) << endl; // 程序員自己創(chuàng)建變量,屬于堆區(qū) int* d_a = new int(10); int* d_b = new int(20); cout << "d_a 的地址為: " << int(d_a) << endl; cout << "d_b 的地址為: " << int(d_b) << endl; }
輸出結(jié)果為:
g_a 的地址為: 5300224 g_b 的地址為: 5300228
a 的地址為: 6421316 b 的地址為: 6421304
s_a 的地址為: 5300232 s_b 的地址為: 5300236
d_a 的地址為: 9547944 d_b 的地址為: 9547992
我們從中可以看到,g_a,g_b,s_a,s_b 都屬于全局區(qū),同理,a,b 都屬于棧區(qū),d_a,d_b 都屬于堆區(qū)。由于棧區(qū)的數(shù)據(jù)在程序運行結(jié)束后會被編譯器自動銷毀,因此不要返回局部變量的地址,舉例如下:
int* func() { int a = 10; // 棧區(qū)數(shù)據(jù),在程序執(zhí)行完之后自動釋放 return &a; //雖然返回了a的地址,然而數(shù)據(jù)在func結(jié)束時已經(jīng)被銷毀 } int main(void) { int* a = func(); // 此時a表示在函數(shù)func在棧區(qū)開辟的地址,但是其中的數(shù)據(jù)已被銷毀 cout << "a 的地址為: " << int(a) << "a 存放的數(shù)據(jù)為: " << *a << endl; cout << "a 的地址為: " << int(a) << "a 存放的數(shù)據(jù)為: " << *a << endl; }
輸出結(jié)果為:
a 的地址為: 7601480a 存放的數(shù)據(jù)為: 10
a 的地址為: 7601480a 存放的數(shù)據(jù)為: 2084553696
由于編譯器會對棧區(qū)的數(shù)據(jù)做一次保留,因此第一條的 cout 語句能夠正常輸出,然而第二次的輸出才是內(nèi)存地址 a 中的數(shù)據(jù)。
相反,堆區(qū)數(shù)據(jù)由程序員自己進行管理,在程序執(zhí)行完之后并不會自動釋放。當整個程序執(zhí)行完畢之后會由操作系統(tǒng)釋放。
int* func() { int * a = new int(10); // 程序員使用new在堆區(qū)開辟空間,在程序執(zhí)行完之后自動釋放 return a; //同樣返回了a的地址,然而只要程序沒有運行結(jié)束,除非程序員釋放,否則會一直保留 } int main(void) { int* a = func(); // 此時a表示在函數(shù)func在堆區(qū)開辟的地址,編譯器無法自動銷毀 cout << "a 的地址為: " << int(a) << "a 存放的數(shù)據(jù)為: " << *a << endl; cout << "a 的地址為: " << int(a) << "a 存放的數(shù)據(jù)為: " << *a << endl; }
輸出結(jié)果為:
a 的地址為: 23507016a 存放的數(shù)據(jù)為: 10
a 的地址為: 23507016a 存放的數(shù)據(jù)為: 10
1、棧區(qū)(stack):就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變量的存儲區(qū)。里面的變量通常是函數(shù)的返回地址、參數(shù)、局部變量、返回值等,從高地址向低地址增長。在一個進程中,位于用戶虛擬地址空間頂部的是用戶棧,編譯器用它來實現(xiàn)函數(shù)的調(diào)用。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。
2、堆區(qū)(heap): 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表,在程序運行過程中可以動態(tài)增加堆大小(移動break指針),從低地址向高地址增長。
堆:是操作系統(tǒng)所維護的一塊特殊內(nèi)存,它提供了動態(tài)分配的功能,當運行程序調(diào)用malloc()時就會從中分配,稍后調(diào)用free()可把內(nèi)存交還。
自由存儲區(qū):自由存儲是C++中通過new和delete動態(tài)分配和釋放對象的抽象概念,通過new來申請的內(nèi)存區(qū)域可稱為自由存儲區(qū)?;旧?,所有的C++編譯器默認使用堆來實現(xiàn)自由存儲,也即是缺省的全局運算符new和delete也許會按照malloc和free的方式來被實現(xiàn),這時藉由new運算符分配的對象,說它在堆上也對,說它在自由存儲區(qū)上也正確。但程序員也可以通過重載操作符,改用其他內(nèi)存來實現(xiàn)自由存儲,例如全局變量做的對象池,這時自由存儲區(qū)和堆區(qū)就有區(qū)別了。
3、數(shù)據(jù)區(qū):主要包括靜態(tài)全局區(qū)和靜態(tài)區(qū),如果要站在匯編角度細分的話還可以分為很多小的區(qū)。
全局區(qū)&靜態(tài)區(qū):全局變量和靜態(tài)變量被分配到同一塊內(nèi)存中,在以前的 C 語言中,全局變量和靜態(tài)變量又分為
全局初始化區(qū)(DATA段) :存儲程序中已初始化的全局變量和靜態(tài)變量
未初始化段(BSS段) :存儲未初始化的全局變量和靜態(tài)變量(局部+全局)。BSS段在DATA段的相鄰的另一塊區(qū)域。
BBS段特點:在程序執(zhí)行前BBS段自動清零,所以未初始化的全局變量和靜態(tài)變量在程序執(zhí)行前已經(jīng)成為0。
在 C++ 里面沒有這個區(qū)分了,他們共同占用同一塊內(nèi)存區(qū)。
4、代碼區(qū):包括只讀存儲區(qū)和文本區(qū),其中只讀存儲區(qū)存儲字符串常量,就是常量區(qū),文本區(qū)存儲程序的機器代碼。
其實“內(nèi)存四區(qū)”和“內(nèi)存五區(qū)”指的東西都是完全一樣的
內(nèi)存五區(qū)為:棧區(qū)、堆區(qū)、全局區(qū)(靜態(tài)區(qū))、常亮區(qū)、代碼區(qū)
內(nèi)存四區(qū)為:棧區(qū)、堆區(qū)、數(shù)據(jù)區(qū)(全局區(qū)(靜態(tài)區(qū))、常亮區(qū))、代碼區(qū)
因此從上面可以看出,對于內(nèi)存四區(qū)而言,其只是把全局區(qū)(靜態(tài)區(qū))和常亮區(qū)合并為一個數(shù)據(jù)區(qū)而已,其實內(nèi)容都是完全一樣的
感謝各位的閱讀,以上就是“C++內(nèi)存四區(qū)是什么”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對C++內(nèi)存四區(qū)是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。