首頁 > 軟體

C++淺析程式中記憶體的分佈

2022-08-15 22:02:25

C++之程式的記憶體分佈

最近在複習C++相關的知識,整理一下。

C++的儲存區主要有以下幾類:

棧區:就是那些由編譯器在需要的時候分配,在不需要的時候自動清楚的變數的儲存區。裡面的變數通常是區域性變數、函數引數等。

堆區:就是那些由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般一個new就要對應一個delete。如果程式設計師沒有釋放掉, 那麼在程式結束後,作業系統會自動回收。只new不delete會造成記憶體漏失。

全域性/靜態儲存區:全域性變數和靜態變數(static修飾的變數)是儲存在同一塊記憶體區域的。以前C語言還區分初始化的和未初始化的全域性變數,將這兩類分別儲存在不同的區域,現在在C++裡這兩者已經不做區分了。

常數儲存區:就是常數字串或者const修飾的變數,該區域的變數不允許修改。

程式碼區(text):存放程式程式碼塊的地方。

這裡通過一個例子來分別看一看這些不同區域的變數。

棧區

    int bb = 1;              // 棧區變數 stack
    char s[] = "abc";       // 棧地址變數
    int *p2 = NULL;         // 棧地址變數

將以上變數的地址分別列印

(lldb) p &bb
(int *) $0 = 0x00000003040cf224
(lldb) p &s
(char (*)[4]) $1 = 0x00000003040cf220
(lldb) p &p2
(int **) $2 = 0x00000003040cf218
(lldb) 

可以看到這幾個儲存在棧區的變數是挨著儲存,且地址依次從高到低變化。

堆區:

    int *ph = new int(10);       // ph在棧區,指向堆(heap)區變數 (地址增長)
    int *ph2 = new int(20);      // 堆(heap)區變數

分別列印指標的地址和指標指向的地址的值

(lldb) p &ph
(int **) $0 = 0x00000003040cf1f0   // 指標的地址,在棧區
(lldb) p &ph2
(int **) $1 = 0x00000003040cf1e8    // 指標的地址,在棧區
(lldb) p ph
(int *) $2 = 0x0000000108e20db0        // 指標指向的地址,在堆區
(lldb) p ph2
(int *) $3 = 0x0000000108e20900        // 指標指向的地址,在堆區

從上面的例子可以看到,指標本身儲存在棧區,其地址相鄰且從高到低變化。

指標指向的地址在另一塊區域,該區域稱為堆區,該區域的地址是從低到高變化的。但是並不具有相鄰的特點。

全域性/靜態儲存區

int globleA = 0;        // 全域性初始化區
int *pPoint;               // 全域性未初始化區 預設為0,指標為NULL
int main(int argc, const char * argv[]) {
    static int c = 0;       // 全域性(靜態)初始化區 (和全域性變數是一樣的)
   	return 0;
}

列印出地址和結果:

(lldb) p &globleA
(int *) $0 = 0x00000001000080d8            // 全域性/靜態變數區
(lldb) p &pPoint
(int **) $1 = 0x00000001000080e0        // 全域性/靜態變數區
(lldb) p &c
(int *) $2 = 0x00000001000080d4        // 全域性靜態變數區
(lldb) p pPoint
(int *) $3 = 0x0000000000000000        // 未初始化的值為NULL

常數區

char *p3 = "123456";    // p3在棧區,但是它指向的變數在常數區(無法改變), 指標可以跨區域存取

(lldb) p p3
(char *) $3 = 0x0000000100003f43 "123456"  // 常數區
(lldb) p &p3
(char **) $4 = 0x00000003040cf210        // 棧區

程式碼區

就是程式碼存放的地方。

下面用一張圖片總結:

到此這篇關於C++淺析程式中記憶體的分佈的文章就介紹到這了,更多相關C++記憶體分佈內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com