

《Unix環境系統高級編程》中的C語言內存分布示意圖
1.C內存分布
BSS段: 用來存放程序中未初始化的全局變量。BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態內存分配。
數據段:用來存放程序中已初始化的全局變量。數據段屬於靜態內存分配。
代碼段:用來存放程序執行代碼。
堆:堆是用於存放進程運行中被動態分配的內存段,它的大小並不固定,可動態擴張或縮減。當進程調用malloc/free等
函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張)/釋放的內存從堆中被剔除(堆被縮減)
棧:棧又稱堆棧, 存放程序的局部變量(但不包括static聲明的變量,static意味着在數據段中存放變量)。除此以外
,在函數被調用時,棧用來傳遞參數和返回值。由於棧的先進先出特點,所以棧特別方便用來保存/恢復調用現場。
2.C++內存分布
a) 棧:內存由編譯器在需要時自動分配和釋放。通常用來存儲局部變量和函數參數。
b) 堆:內存使用new進行分配使用delete或delete[]釋放。如果未能對內存進行正確的釋放,會造成內存泄漏。但在程序結束時,會由操作系統自動回收。
c) 自由存儲區:使用malloc進行分配,使用free進行回收。和堆類似。
d) 全局/靜態存儲區:全局變量和靜態變量被分配到同一塊內存中,C語言中區分初始化和未初始化的,C++中不再區分了。
e) 常量存儲區:存儲常量,不允許被修改。
3.區分棧和堆
a) 管理方式:棧由編譯器管理,堆由程序員控制。
b) 空間大小:VC下棧默認是1MB,堆在32位的系統上可以達到4GB。
c) 碎片問題:棧不會產生碎片,堆會產生碎片。
d) 生長方向:堆向着內存地址增加的方向增長,棧向着內存地址減少的方向增長。
e) 分配方式:堆是動態分配的。棧是靜態分配和動態分配的,靜態分配由編譯器完成,動態分配由alloca函數進行分配,由編譯器釋放。
f) 分配效率:棧的分配效率非常高。堆的分配機制很復雜,效率比棧要低得多。
4.malloc的實現
http://www.ibm.com/developerworks/cn/linux/l-memory/
5. C++智能指針
a) auto_ptr: C++03標准,方便管理單個堆對象的內存,不能配合容器使用,賦值操作會轉移指針所有權,release()會交出指針所有權。
b) unique_ptr: C++11標准,方便管理堆對象或者堆對象數組的內存,一旦初始化,不會再交出指針所有權,可以避免很多錯誤的實踐。
c) shared_ptr:C++11標准,方便管理需要共享所有權的內存,可以配合容器使用,可以用在參數傳遞的過程。
d) weak_ptr:C++11標准,weak_ptr是shared_ptr的觀察者,負責從shared_ptr產生一個weak_ptr但是不會增加引用計數,當shread_ptr失效以后,weak_ptr也會失效。
e) 如何選擇:不要使用auto_ptr,不要使用裸指針,局部變量使用unique_ptr需要傳遞和共享的指針使用shared_ptr。
