C語言內存模型


一、程序在內存中被執行的過程

流程說明
1、操作系統把物理硬盤代碼load到內存
2、操作系統把c代碼分成四個區
3、操作系統找到main函數入口執行

二、四區的說明

一個由c/C++編譯的程序占用的內存分為以下幾個部分
1、棧區(stack):由編譯器自動分配釋放 ,存放函數的參數值,局部變量的值等。其操作方式同數據結構中的棧(FILO)。


2、堆區(heap: 一般由程序員分配釋放, 若程序員不釋放,程序結束時可能由OS回收 。注意它與數據結構中的堆是兩回事,分配方式倒是類似於鏈表。

(需要malloc-free;new-delete;new[]-delete[])

 

3、數據區:主要包括靜態全局區和常量區,如果要站在匯編角度細分的話還可以分為很多小的區。
           全局區(靜態區)(static):全局變量和靜態變量的存儲是放在一塊的,初始化的全局變量和靜態變量在一塊區域, 未初始化的全局變量和未初始化的靜態變量在相鄰的另一塊區域。 程序結束后有系統釋放

   常量區 :常量字符串就是放在這里的。 程序結束后由系統釋放。

 

4、代碼區:存放函數體的二進制代碼。

5、內存的物理結構

一般內存四區中的棧的開口方向是向下的。為什么要這樣設計呢,因為設計棧的方向向下,可以給應用程序設定棧的大小,這樣就可以避免棧溢出。

不管棧是開口向上還是開口向下,BUFF的增長方向都是向上的。可以通過代碼測出來。

如果棧的開口方向向下,那么BUFF的基址在下面,如果棧的開口方向向上,BUFF的基址也在下面,也就是說,不管棧的開口方向朝那里,BUFF的基址都在下面

三、函數調用說明

在操作系統調用main函數的時候,會將main函數的返回地址和參數入棧,然后開始直行main函數,如果在main函數中調用了其他函數,會先將main函數的運行狀態入棧,然后將被調用函數的返回值入棧,被調用函數的參數入棧,然后去執行被調用函數,如果還有其他調用函數,過程也是類似的。

在main函數中分配的內存,被調用函數是可以使用的。

main函數可以在棧上,堆上,全局區上進行分配內存,這些內存是可以被函數中被調用函數使用的。

而在被調用函數中棧上分配的內存,不能被主調函數使用,像堆上,還有全局區上分配的內存,都可以供主調函數使用,通過間接賦值的方式將內存的首地址傳遞出來就可以了。

四、總結

1、主調函數分配的內存空間(堆,棧,全局區)可以在被調用函數中使用,可以以指針作函數參數的形式來使用

2、被調用函數分配的內存空間只有堆區和全局區可以在主調函數中使用(返回值和函數參數),而棧區卻不行,因為棧區函數體運行完之后內存管理器自動釋放。

3、一定要明白函數的主被調關系以及主被調函數內存分配回收


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM