C && C++ 內存分配示意圖


《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。


免責聲明!

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



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