C++的代碼區(qū)、全局區(qū)、棧區(qū)和堆區(qū)是什么

本篇內(nèi)容主要講解“C++的代碼區(qū)、全局區(qū)、棧區(qū)和堆區(qū)是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“C++的代碼區(qū)、全局區(qū)、棧區(qū)和堆區(qū)是什么”吧!

10余年的張店網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整張店建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“張店網(wǎng)站設(shè)計(jì)”,“張店網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

C++內(nèi)存四區(qū)

C++ 在程序執(zhí)行時(shí),將內(nèi)存大致分為代碼區(qū),全局區(qū),棧區(qū)和堆區(qū)四個(gè)區(qū)域。不同的區(qū)域存儲(chǔ)不同的數(shù)據(jù),賦予不同的生命周期,能夠更靈活地進(jìn)行編程。

  1. 代碼區(qū):存放函數(shù)體的二進(jìn)制代碼,由操作系統(tǒng)管理創(chuàng)建,代碼區(qū)時(shí)共享的,對于頻繁被執(zhí)行的程序,只需要存有一份代碼即可;

  2. 全局區(qū):存放全局變量和靜態(tài)變量以及常量,在程序結(jié)束后由操作系統(tǒng)釋放;

  3. 棧區(qū):由編譯其自動(dòng)分配釋放,存放函數(shù)的參數(shù)值以及局部變量等;

  4. 堆區(qū):一般由程序員通過 new 開辟空間,進(jìn)行分配和釋放,若程序員不釋放,則程序結(jié)束時(shí)由操作系統(tǒng)回收

下面通過一個(gè)例子對全局區(qū),棧區(qū),堆區(qū)的數(shù)據(jù)聲明周期進(jìn)行說明:

// 全局變量屬于全局區(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ù)在程序運(yùn)行結(jié)束后會(huì)被編譯器自動(dòng)銷毀,因此不要返回局部變量的地址,舉例如下:

int* func()
{
 int a = 10; // 棧區(qū)數(shù)據(jù),在程序執(zhí)行完之后自動(dòng)釋放
 return &a; //雖然返回了a的地址,然而數(shù)據(jù)在func結(jié)束時(shí)已經(jīng)被銷毀
}

int main(void)
{
 int* a = func(); // 此時(shí)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

由于編譯器會(huì)對棧區(qū)的數(shù)據(jù)做一次保留,因此第一條的 cout 語句能夠正常輸出,然而第二次的輸出才是內(nèi)存地址 a 中的數(shù)據(jù)。

相反,堆區(qū)數(shù)據(jù)由程序員自己進(jìn)行管理,在程序執(zhí)行完之后并不會(huì)自動(dòng)釋放。當(dāng)整個(gè)程序執(zhí)行完畢之后會(huì)由操作系統(tǒng)釋放。

int* func()
{
 int * a = new int(10); // 程序員使用new在堆區(qū)開辟空間,在程序執(zhí)行完之后自動(dòng)釋放
 return a; //同樣返回了a的地址,然而只要程序沒有運(yùn)行結(jié)束,除非程序員釋放,否則會(huì)一直保留
}

int main(void)
{
 int* a = func(); // 此時(shí)a表示在函數(shù)func在堆區(qū)開辟的地址,編譯器無法自動(dòng)銷毀
 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

附:內(nèi)存四區(qū)的小結(jié)

1、棧區(qū)(stack):就是那些由編譯器在需要的時(shí)候分配,在不需要的時(shí)候自動(dòng)清除的變量的存儲(chǔ)區(qū)。里面的變量通常是函數(shù)的返回地址、參數(shù)、局部變量、返回值等,從高地址向低地址增長。在一個(gè)進(jìn)程中,位于用戶虛擬地址空間頂部的是用戶棧,編譯器用它來實(shí)現(xiàn)函數(shù)的調(diào)用。其操作方式類似于數(shù)據(jù)結(jié)構(gòu)中的棧。

2、堆區(qū)(heap): 一般由程序員分配釋放, 若程序員不釋放,程序結(jié)束時(shí)可能由OS回收 。注意它與數(shù)據(jù)結(jié)構(gòu)中的堆是兩回事,分配方式倒是類似于鏈表,在程序運(yùn)行過程中可以動(dòng)態(tài)增加堆大小(移動(dòng)break指針),從低地址向高地址增長。

        堆:是操作系統(tǒng)所維護(hù)的一塊特殊內(nèi)存,它提供了動(dòng)態(tài)分配的功能,當(dāng)運(yùn)行程序調(diào)用malloc()時(shí)就會(huì)從中分配,稍后調(diào)用free()可把內(nèi)存交還。

        自由存儲(chǔ)區(qū):自由存儲(chǔ)是C++中通過new和delete動(dòng)態(tài)分配和釋放對象的抽象概念,通過new來申請的內(nèi)存區(qū)域可稱為自由存儲(chǔ)區(qū)?;旧希械腃++編譯器默認(rèn)使用堆來實(shí)現(xiàn)自由存儲(chǔ),也即是缺省的全局運(yùn)算符new和delete也許會(huì)按照malloc和free的方式來被實(shí)現(xiàn),這時(shí)藉由new運(yùn)算符分配的對象,說它在堆上也對,說它在自由存儲(chǔ)區(qū)上也正確。但程序員也可以通過重載操作符,改用其他內(nèi)存來實(shí)現(xiàn)自由存儲(chǔ),例如全局變量做的對象池,這時(shí)自由存儲(chǔ)區(qū)和堆區(qū)就有區(qū)別了。

3、數(shù)據(jù)區(qū):主要包括靜態(tài)全局區(qū)和靜態(tài)區(qū),如果要站在匯編角度細(xì)分的話還可以分為很多小的區(qū)。

        全局區(qū)&靜態(tài)區(qū):全局變量和靜態(tài)變量被分配到同一塊內(nèi)存中,在以前的 C 語言中,全局變量和靜態(tài)變量又分為

全局初始化區(qū)(DATA段) :存儲(chǔ)程序中已初始化的全局變量和靜態(tài)變量

未初始化段(BSS段) :存儲(chǔ)未初始化的全局變量和靜態(tài)變量(局部+全局)。BSS段在DATA段的相鄰的另一塊區(qū)域。

   BBS段特點(diǎn):在程序執(zhí)行前BBS段自動(dòng)清零,所以未初始化的全局變量和靜態(tài)變量在程序執(zhí)行前已經(jīng)成為0。

在 C++ 里面沒有這個(gè)區(qū)分了,他們共同占用同一塊內(nèi)存區(qū)。

4、代碼區(qū):包括只讀存儲(chǔ)區(qū)和文本區(qū),其中只讀存儲(chǔ)區(qū)存儲(chǔ)字符串常量,就是常量區(qū),文本區(qū)存儲(chǔ)程序的機(jī)器代碼。

那“內(nèi)存四區(qū)”和“內(nèi)存五區(qū)”有什么區(qū)別嗎?

其實(shí)“內(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ū)合并為一個(gè)數(shù)據(jù)區(qū)而已,其實(shí)內(nèi)容都是完全一樣的

到此,相信大家對“C++的代碼區(qū)、全局區(qū)、棧區(qū)和堆區(qū)是什么”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

文章題目:C++的代碼區(qū)、全局區(qū)、棧區(qū)和堆區(qū)是什么
文章出自:http://muchs.cn/article8/ppjgip.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司全網(wǎng)營銷推廣、App設(shè)計(jì)、手機(jī)網(wǎng)站建設(shè)、App開發(fā)、網(wǎng)站改版

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司