91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C++的代碼區、全局區、棧區和堆區是什么

發布時間:2022-03-28 09:52:16 來源:億速云 閱讀:304 作者:iii 欄目:大數據

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

C++內存四區

C++ 在程序執行時,將內存大致分為代碼區,全局區,棧區和堆區四個區域。不同的區域存儲不同的數據,賦予不同的生命周期,能夠更靈活地進行編程。

  1. 代碼區:存放函數體的二進制代碼,由操作系統管理創建,代碼區時共享的,對于頻繁被執行的程序,只需要存有一份代碼即可;

  2. 全局區:存放全局變量和靜態變量以及常量,在程序結束后由操作系統釋放;

  3. 棧區:由編譯其自動分配釋放,存放函數的參數值以及局部變量等;

  4. 堆區:一般由程序員通過 new 開辟空間,進行分配和釋放,若程序員不釋放,則程序結束時由操作系統回收

下面通過一個例子對全局區,棧區,堆區的數據聲明周期進行說明:

// 全局變量屬于全局區,由操作系統管理釋放
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;
 // 創建普通的局部變量,屬于棧區
 int a = 10;
 int b = 20; 
 cout << "a 的地址為:	" << int(&a) << endl;
 cout << "b 的地址為:	" << int(&b) << endl;
 // 創建靜態變量,屬于全局區
 static int s_a = 40;
 static int s_b = 50;
 cout << "s_a 的地址為:	" << int(&s_a) << endl;
 cout << "s_b 的地址為:	" << int(&s_b) << endl;
 // 程序員自己創建變量,屬于堆區
 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;
}

輸出結果為:

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 都屬于全局區,同理,a,b 都屬于棧區,d_a,d_b 都屬于堆區。由于棧區的數據在程序運行結束后會被編譯器自動銷毀,因此不要返回局部變量的地址,舉例如下:

int* func()
{
 int a = 10; // 棧區數據,在程序執行完之后自動釋放
 return &a; //雖然返回了a的地址,然而數據在func結束時已經被銷毀
}

int main(void)
{
 int* a = func(); // 此時a表示在函數func在棧區開辟的地址,但是其中的數據已被銷毀
 cout << "a 的地址為:	" << int(a) << "a 存放的數據為:	" << *a << endl;
 cout << "a 的地址為:	" << int(a) << "a 存放的數據為:	" << *a << endl;
}

輸出結果為:

a 的地址為:    7601480a 存放的數據為: 10
a 的地址為:    7601480a 存放的數據為: 2084553696

由于編譯器會對棧區的數據做一次保留,因此第一條的 cout 語句能夠正常輸出,然而第二次的輸出才是內存地址 a 中的數據。

相反,堆區數據由程序員自己進行管理,在程序執行完之后并不會自動釋放。當整個程序執行完畢之后會由操作系統釋放。

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

int main(void)
{
 int* a = func(); // 此時a表示在函數func在堆區開辟的地址,編譯器無法自動銷毀
 cout << "a 的地址為:	" << int(a) << "a 存放的數據為:	" << *a << endl;
 cout << "a 的地址為:	" << int(a) << "a 存放的數據為:	" << *a << endl;
}

輸出結果為:

a 的地址為:    23507016a 存放的數據為:        10
a 的地址為:    23507016a 存放的數據為:        10

附:內存四區的小結

1、棧區(stack):就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變量的存儲區。里面的變量通常是函數的返回地址、參數、局部變量、返回值等,從高地址向低地址增長。在一個進程中,位于用戶虛擬地址空間頂部的是用戶棧,編譯器用它來實現函數的調用。其操作方式類似于數據結構中的棧。

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

        堆:是操作系統所維護的一塊特殊內存,它提供了動態分配的功能,當運行程序調用malloc()時就會從中分配,稍后調用free()可把內存交還。

        自由存儲區:自由存儲是C++中通過new和delete動態分配和釋放對象的抽象概念,通過new來申請的內存區域可稱為自由存儲區。基本上,所有的C++編譯器默認使用堆來實現自由存儲,也即是缺省的全局運算符new和delete也許會按照malloc和free的方式來被實現,這時藉由new運算符分配的對象,說它在堆上也對,說它在自由存儲區上也正確。但程序員也可以通過重載操作符,改用其他內存來實現自由存儲,例如全局變量做的對象池,這時自由存儲區和堆區就有區別了。

3、數據區:主要包括靜態全局區和靜態區,如果要站在匯編角度細分的話還可以分為很多小的區。

        全局區&靜態區:全局變量和靜態變量被分配到同一塊內存中,在以前的 C 語言中,全局變量和靜態變量又分為

    全局初始化區(DATA段) :存儲程序中已初始化的全局變量和靜態變量

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

              BBS段特點:在程序執行前BBS段自動清零,所以未初始化的全局變量和靜態變量在程序執行前已經成為0。

  在 C++ 里面沒有這個區分了,他們共同占用同一塊內存區。

4、代碼區:包括只讀存儲區和文本區,其中只讀存儲區存儲字符串常量,就是常量區,文本區存儲程序的機器代碼。

那“內存四區”和“內存五區”有什么區別嗎?

其實“內存四區”和“內存五區”指的東西都是完全一樣的

內存五區為:棧區、堆區、全局區(靜態區)、常亮區、代碼區

內存四區為:棧區、堆區、數據區(全局區(靜態區)、常亮區)、代碼區

因此從上面可以看出,對于內存四區而言,其只是把全局區(靜態區)和常亮區合并為一個數據區而已,其實內容都是完全一樣的

到此,相信大家對“C++的代碼區、全局區、棧區和堆區是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

剑川县| 辉县市| 丰县| 息烽县| 霸州市| 东阳市| 建湖县| 霍山县| 松江区| 明溪县| 镇江市| 子长县| 泸州市| 古田县| 松江区| 连州市| 太湖县| 百色市| 泽库县| 灵宝市| 江孜县| 繁昌县| 新宁县| 加查县| 武威市| 永和县| 光泽县| 天台县| 云霄县| 灵璧县| 茌平县| 德庆县| 大余县| 沭阳县| 呼图壁县| 和硕县| 云南省| 巫溪县| 巩义市| 顺义区| 大足县|