C和C 中的記憶體分配

2022-08-19 10:15:11 字數 1104 閱讀 4286

最近在課堂上聽到老師講了c語言中的記憶體分配,感覺挺深刻的,於是就寫下來,當做是對自己的提醒!

微機原理的知識告訴我們,記憶體大致可以分為三部分:**區 、堆疊區、資料段(我的計算機學的不好,按照自己的理解)。c和c++中有全域性變數,靜態變數以及區域性變數等幾類。全域性變數和靜態變數是在編譯的時候就已經分配好在資料段,也就是說在執行main函式之前就已經分配好了位址,如果定義的時候認為初始化,那麼就存放初始化的值,如果沒有初始化,則由編譯器初始化為0。這就說明在整個程式的執行過程中全域性變數和靜態變數的位址和型別不會發生變化,可能變化的只是他的值。

對於動態變數,則在編譯的階段並不分配記憶體,而是執行到相應的**段時再分配記憶體。區域性變數共有以下幾種:

1    int main(void)

int a;//區域性變數定義於main中;

int a;//區域性變數定義於**段內;

2    void fun()

int a;//區域性變數定義於普通函式內;

3    void fun(int a,int b)//形式引數

編譯器對區域性變數的處理是放入棧中,學過微機原理知道,出棧和入棧操作的運算元都是跟著指令,存在於**段內的,當函式執行到區域性變數出,進行入棧操作,給他分配棧中的記憶體,供其它操作訪問。在使用結束後再出棧。所以,區域性變數的生存期是從定義的地方到該函式結束和**段結束。

對應情況1第乙個,在main函式結束時出棧,第二個在{}內的**執行結束後出棧。這也很好理解,函式的呼叫本身就涉及到對指令位址的入棧操作,呼叫結束後涉及到指令位址的出棧操作:模擬一下如下函式的棧活動:

void fun1(int a)                              

int b;

main()

int a;

fun1();

過程:執行到main函式,對cpu ip的指標入棧:入棧1,保護現場環境(這裡簡化入棧操作) 給區域性變數a入棧分配棧記憶體:入棧2。執行fun1(),對cpu ip的指標入棧:入棧3,保護現場。給形參a入棧,分配棧記憶體,入棧4,給區域性變數b分配棧記憶體,入棧5,。執行完函式的呼叫,恢復現場,對入棧5出棧,對入棧4出棧,對cpu ip出棧,函式呼叫完畢。然後main函式內執行完畢,對入棧2出棧,對入棧1出棧。至此可以看出區域性變數的生存期。

C和C 中記憶體分配的細節

精煉易懂,bss段 用來存放程式中未初始化的全域性變數。bss是英文block started by symbol的簡稱。bss段屬於靜態記憶體分配。資料段 用來存放程式中已初始化的全域性變數。資料段屬於靜態記憶體分配。段 用來存放程式執行 這 堆 堆是用於存放程序執行中被動態分配的記憶體段,它的大...

c和c 中的記憶體分配和記憶體釋放函式

c語言中的free 對應malloc 或delete 對應c 中的new 來釋放 例 char pt1,pt2 pt1 char malloc 100 pt2 pt1 free pt1 pt1 null return 0 第一行定義兩個字元指標,但沒有賦初值,編譯器只給pt1 pt2個分配兩個位元組...

C 中的記憶體分配

在c 中,記憶體分成5個區,他們分別是堆 棧 自由儲存區 全域性 靜態儲存區和常量儲存區堆 堆就是那些由 new 分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般乙個 new 就 要對應乙個 delete。如果程式設計師沒有釋放掉,那麼在程式結束後,作業系統會自動 堆可以動態地擴...