### 內存分區
C代碼經過**預處理、編譯、匯編、鏈接**4步后生成一個可執行程序。
在 Linux 下,程序是一個普通的可執行文件,以下列出一個二進制可執行文件的基本情況:

通過上圖可以得知,在沒有運行程序前,也就是說**程序沒有加載到內存前**,可執行程序內部已經分好3段信息,分別為**代碼區(text)、數據區(data)和未初始化數據區(bss)**3 個部分(有些人直接把data和bss合起來叫做靜態區或全局區)。
* **代碼區**
存放 CPU 執行的機器指令。通常代碼區是可共享的(即另外的執行程序可以調用它),使其可共享的目的是對于頻繁被執行的程序,只需要在內存中有一份代碼即可。**代碼區通常是只讀的**,使其只讀的原因是防止程序意外地修改了它的指令。另外,代碼區還規劃了局部變量的相關信息。
* **全局初始化數據區/靜態數據區(data段)**
該區包含了在程序中明確被初始化的全局變量、已經初始化的靜態變量(包括全局靜態變量和局部靜態變量)和常量數據(如字符串常量)。
* **未初始化數據區(又叫 bss 區)**
存入的是全局未初始化變量和未初始化靜態變量。未初始化數據區的數據在程序開始執行之前被內核初始化為 0 或者空(NULL)。

* **代碼區(text segment)**
加載的是可執行文件代碼段,所有的可執行代碼都加載到代碼區,這塊內存是不可以在運行期間修改的。
* **未初始化數據區(BSS)**
加載的是可執行文件BSS段,位置可以分開亦可以緊靠數據段,存儲于數據段的數據(全局未初始化,靜態未初始化數據)的生存周期為整個程序運行過程。
* **全局初始化數據區/靜態數據區(data segment)**
加載的是可執行文件數據段,存儲于數據段(全局初始化,靜態初始化數據,文字常量(只讀))的數據的生存周期為整個程序運行過程。
* **棧區(stack)**
棧是一種先進后出的內存結構,由編譯器自動分配釋放,存放函數的參數值、返回值、局部變量等。在程序運行過程中實時加載和釋放,因此,局部變量的生存周期為申請到釋放該段棧空間。
* **堆區(heap)**
堆是一個大容器,它的容量要遠遠大于棧,但沒有棧那樣先進后出的順序。用于動態內存分配。堆在內存中位于BSS區和棧區之間。一般由程序員分配和釋放,若程序員不釋放,程序結束時由操作系統回收。

