C 內存模型和智能指針

參考:https://www.cnblogs.com/shilinnpu/p/8873271.html

c++的內存分爲

1.全局和靜態存儲區(.data segment和.bss segment)

全局和靜態被分配到一塊內存裏

在c裏面

bss(Block Started by Symbol以符號開始的塊):.bss保存只有聲明沒有初始化的全局變量

.data 數據段:一般存放已經初始化的全局變量

現在c++裏面已經不分了

2.常量存儲區(.rodata segment)

存放常量,不能修改

3.堆heap

用戶自己管理的動態內存,如果用戶不釋放,程序結束後,os回收

new運算符

可以確保調用對象的構造函數之前,堆內存是開闢成功的,new操作符返回一個指向類對象的指針,delete刪除內存,沒有刪除會造成內存泄漏

Person* p=new Person();

malloc(函數)

不會調用構造函數,只能確定開闢內存的大小,不能確定裏面是否有垃圾數據,返回void*,free刪除內存

malloc(sizeof(int));

4.棧stack

  •  編譯器自動分配
  • 存放局部變量,函數參數值
  • 存放在棧中的數據只在當前函數及下一層函數中有效,一旦函數返回了,這些數據也就自動釋放了。

每當一個函數被調用,這個函數的地址和一些關於調用的信息(比如某些寄存器的內容)就會被儲存到棧區

然後這個被調用的函數再爲它的自動變量和臨時變量在棧區上分配空間,這就是C實現 函數遞歸調用的方法。每執行一次遞歸函數調用,一個新的棧框架就會被使用,這樣這個新實例棧裏的變量就不會和該函數的另一個實例棧裏面的變量混淆。

5.代碼區(.text)

編譯後的函數,機器碼


Linux下,程序在內存裏的分佈:

 

 


按程序在內存中駐留的時間分

1靜態內存

包含  局部靜態變量   當經過初始化語句被加載進內存,直到程序結束

         類靜態數據成員     類內靜態變量

                                       類內靜態函數

         定義在任何函數之外的變量(全局變量)

2動態內存

我們常說的heap內存,每一個程序都有一個內存池,這部分被稱爲自由空間即堆內存,動態對象的生命週期由程序決定

3棧內存

僅在定義的程序塊內有效,由編譯器自動創建和銷燬


智能指針

對動態內存的管理很麻煩,如果new後沒有delete,就會造成內存泄漏,非法內存(淺拷貝,對同一塊內存釋放兩次)

c++11新標準提供了兩種  智能指針 smart pointer  類型來管理對象

粗理解

傳入一個對象的指針給智能指針  例如   People*  p,把這個指針p託管給智能指針,智能指針析構的時候對p指向的內存進行釋放

shared_ptr允許多個指針指向同一個對象

unique_ptr 獨佔指向的對象

weak_ptr是shared_ptr伴隨類,它是一種弱引用,指向shared_ptr所管理的對象

shared_ptr,unique_ptr,weak_ptr都是定義在memory頭文件中


shared_ptr類

智能指針也是一種模板,所以當我們創建智能指針時,必須額外提供一個信息-----指針可以指向的類型

shared_ptr<string> p1     p1可以指向string類型的對象

shared_ptr<list<int>> p2    p2可以指向int的list的對象

默認初始化的智能指針裏包含一個空指針


shared_ptr和unique_ptr都可以有的操作

  • shared_ptr<T> sp      空智能指針,可以指向類型爲T的對象
  • unique_ptr<T> up   
  • p         將p作爲一個判斷對象,若p指向一個對象,則爲true
  • *p        解引用P,獲得它指向的對象
  • p->men      等價於(*p).men
  • p.get()      返回p中保留的指針。若智能指針釋放了對象,返回的指針所指向的對象也就消失了
  • swap(p,q)交換p和q中的指針
  • p.swap(q)

shared_ptr獨有的操作

make_ptr<T>(args)    返回一個shared_ptr,指向一個動態分配的類型爲T的對象,使用args初始化這個對象

shared_ptr<T>p(q)   p是shared_ptr的拷貝,q的計數器+1,q中的指針必須能轉化成爲T*  ,就是說q中的指針所指向的對象一定能轉換可以傳換成T的類型       X=T         X*=>T*

p=q     p和q都是shared_ptr,所保存的指針必須能互相轉化,遞減p的引用次數,遞增q的引用次數,如p減爲0,將其管理的內存釋放

p.unique()      若

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章