c 指標和動態記憶體管理

2021-10-03 01:15:08 字數 4094 閱讀 4486

c++中動態記憶體的管理主要是使用new/delete表示式和std::allcator類。為了管理動態記憶體更加安全,c++11新標準庫推出了智慧型指標。

new/delete

new完成的操作:

(1): 它分配足夠儲存乙個特定型別物件的記憶體

(2):為它剛才分配的記憶體中的那個物件設定初始值。(對於內建型別物件,就是預設初始化該它,對應類型別,呼叫constructor初始化)

delete完成的操作:

(1):銷毀給定指標指向的物件

(2):釋放該物件的對應記憶體

常見問題

1.申請的空間沒有進行釋放,會出現記憶體洩漏。這種忘記釋放的記憶體如果不退出程式將永遠不會歸還給系統。解決方法:

int

*p=new

int(0)

;delete p;

p=nullptr

;//釋放該指標後指向空,一可以避免再次訪問它出現未定義行為,二可以避免再次delete它出現未定義行為。

int

*pa;

delete pa;

2.使用已經釋放記憶體的物件解決方法:對已經釋放的記憶體物件賦給乙個空指標,在使用前判斷是否為空指標。

int

*p=new

int(0)

;delete p;

p=nullptr

;//也可=null/0

//......

if(p)

3.同一塊記憶體釋放兩次,雖然這個問題聽起來不太可能發生,但當有兩個指標指向同一塊記憶體時,可能就容易發生了。避免方法:delete後直接將記憶體物件置為空指標。

智慧型指標的使用及原理

什麼是智慧型指標?

智慧型指標是乙個類,這個類的建構函式中傳入乙個普通指標,析構函式中釋放傳入的指標。智慧型指標的類都是棧上的物件,所以當函式(或程式)結束時會自動被釋放,

rall

rall是一種利用物件生命週期來控制程式資源(如記憶體、檔案控制代碼、網路連線、互斥量等)的技術。

在物件構造時獲取資源,接著控制對資源的訪問使之在物件的生命週期內始終保持有效,最後在物件析構的時候釋放資源。藉此,我們實際上把管理乙份資源的責任託管給了乙個物件。這種做法有兩大好處:

智慧型指標的原理

raii特性

過載operator*和opertaor->,從而具有指標一樣的行為。

使用rall思想設計智慧型指標:

template

<

class

t>

class

smartptr

~smartptr()

t&operator*(

) t*

operator

->()

private

: t* _ptr;};

struct date

}

std::auto_ptr

auto_ptr的實現原理:管理權轉移/轉移資源的思想。在c++98中提供,盡量不要使用。

template

<

class

t>

class

autoptr

~autoptr()

autoptr

(autoptr

& ap)

:_ptr

(ap._ptr)

autoptr

&operator

=(autoptr

& ap)

return

*this;}

t&operator*(

) t*

operator

->()

private

: t* _ptr;

};

注意

不要使用auto_ptr儲存乙個非動態開闢空間的指標,因為在作用域結束的時候,會執行智慧型指標的析構函式,釋放這塊空間,但非動態的空間又無法釋放;

不要使用兩個auto_ptr指標指向同乙個指標,因為會產生額外開銷;

不要使用auto_ptr指向乙個指標陣列,因為auto_ptr的析構函式所用的是delete而不是delete;

不要將auto_ptr儲存在容器中,因為賦值和拷貝構造後原指標無法使用。

std::unique_ptr

unique_ptr的實現原理:防拷貝,c++11中實現。

template

<

class

t>

class

uniqueptr

~uniqueptr()

t&operator*(

) t*

operator

->()

private

:// c++98防拷貝的方式:只宣告不實現+宣告成私有

uniqueptr

(uniqueptr

const&)

; uniqueptr &

operator

=(uniqueptr

const&)

;// c++11防拷貝的方式:delete

uniqueptr

(uniqueptr

const&)

=delete

; uniqueptr &

operator

=(uniqueptr

const&)

=delete

;private

: t * _ptr;

};

std::shared_ptr

shared_ptr的原理:是通過引用計數的方式來實現多個shared_ptr物件之間共享資源。

注意

shared_ptr在其內部,給每個資源都維護了著乙份計數,用來記錄該份資源被幾個物件共享。

在物件被銷毀時(也就是析構函式呼叫),就說明自己不使用該資源了,物件的引用計數減一。

如果引用計數是0,就說明自己是最後乙個使用該資源的物件,必須釋放該資源;

如果不是0,就說明除了自己還有其他物件在使用該份資源,不能釋放該資源,否則其他物件就成野指標了。

#include

#include

template

<

class

t>

class

sharedptr

~sharedptr()

sharedptr

(const sharedptr

& sp)

:_ptr

(sp._ptr)

,_prefcount

(sp._prefcount)

,_pmutex

(sp._pmutex)

// sp1 = sp2

sharedptr

&operator=(

const sharedptr

& sp)

return

*this;}

t&operator*(

) t*

operator

->()

intusecount()

t*get()

void

addrefcount()

private

:void

release()

_pmutex.

unlock()

;if(deleteflag ==

true

)delete _pmutex;

}private

:int

* _prefcount;

// 引用計數

t* _ptr;

// 指向管理資源的指標

mutex* _pmutex;

// 互斥鎖

};

關於這個智慧型指標的一些問題:

迴圈引用

執行緒安全

記憶體洩漏

C和指標 動態記憶體分配

void malloc size t size 分配所需的記憶體空間,並返回乙個指向它的指標。記憶體塊的大小,以位元組為單位。void calloc unsigned int num,unsigned int size 功能 在記憶體的動態儲存區中分配num個長度為size的連續空間,函式返回乙個指...

C 動態記憶體管理

我們都知道在c 中可以用new malloc動態分配記憶體空間,delete free釋放動態開闢的記憶體空間。1.那麼既然c 中有了可以動態開闢記憶體的函式為什麼又要有new delete呢?c 中的malloc free是繼承c語言中的malloc free,它的用法和在c語言中的用法一模一樣。...

C 動態記憶體管理

1 總結並剖析malloc free和new delete之間關係和差異。1 他們都是動態記憶體管理的入口 2 malloc要計算空間大小,返回值要強轉 new自動計算位元組大小,返回值是相應型別的指標 3 malloc只開闢空間 new開闢空間 呼叫建構函式初始化 delete呼叫析構函式清理 釋...