C 防止資源沒有及時釋放的方法

2021-09-25 09:08:41 字數 3976 閱讀 4490

看如下**:

#include using namespace std;

int main()

else

delete tmp;

}

我們看到當第乙個if語句滿足條件,程式退出後,並沒有正常釋放tmp所占有的外部資源造成了資源的浪費,即所謂的記憶體洩漏。

我們在日常開發的時候可能會經常的碰到這種情況的。所以我們引出了智慧型指標的概念。

利用物件出自已的作用域自動呼叫析構函式的特性實現我們自己的智慧型指標。

#include using namespace std;

templateclass smartptr

~smartptr()

t &operator*()

t *operator->()

private:

t *_mptr;

};int main()

int main()

利用上面自己實現的智慧型指標類,執行上面的**我們發現程式直接奔潰,因為發生了淺拷貝問題

那麼怎麼解決我們智慧型指標發生的淺拷貝問題呢????

這裡有倆種,

首先,不帶引用計數的智慧型指標,系統中有三個

(庫裡面有的)

auto_ptr

(c++新標準)

scoped_ptr

unique_ptr

auto_ptr不推薦使用這個;

auto_ptr(auto_ptr& _right) noexcept

: _myptr(_right.release())

_ty * release() noexcept

_ty * _tmp = _myptr;

_myptr = nullptr;

return (_tmp);

}

我們根據auto_ptr的拷貝建構函式可以看出來:每次給另外乙個物件拷貝構造的時候,就把被拷貝構造的底層指標置為空,無法再次訪問了。所以我們並不推薦使用這個智慧型指標,除非你的應用場景特別簡單的情況下可以使用。scoped_ptrscoped_ptr(const scoped_ptr&) = delete;scoped_ptr operator=(const scoped_ptr&)=delete;

推薦使用

unique_ptr(它本身相當於提供了帶右值引用的拷貝建構函式和賦值函式,帶左值得拷貝構造和賦值函式和scoped_ptr一樣被刪除(delete)掉了。)

unique_ptrp1(new int);

unique_ptrp2(std::move(p1));

這裡相當於呼叫了move語義轉化將p1持有得資源移動到p2上。移動完成後,p1不再持有任何資源,也無法訪問了。

#include using namespace std;

templateclass refcnt

void addref() //新增引用計數

int delref()

private:

t *mptr;

int mcount;

};templateclass smartptr

~smartptr() }

t &operator*()

t *operator->()

smartptr(const smartptr&src)

:_mptr(src._mptr)

, mprefcnt(src.mprefcnt)

smartptr& operator=(const smartptr&src)

_mptr = src._mptr;

mprefcnt = src.mprefcnt;

mprefcnt->addref();

return *this;

}private:

t *_mptr;

refcnt*mprefcnt;

};int main()

結果:

可見帶引用計數的ptr可以使得多個智慧型指標引用同一塊記憶體。

shared_ptr強智慧型指標                可以改變資源的引用的計數

weak_ptr弱智能指標                     不會改變資源的引用的計數

弱智能指標觀察強智慧型指標,強智慧型指標觀察資源。

強智慧型指標迴圈引用是什麼問題?什麼結果?如何解決。

#include #include using namespace std;

class b;

class a

~a()

shared_ptr_ptrb;

};class b

~b()

shared_ptr_ptra;

};int main()

結果:

無法達到析構的條件,造成了嚴重的資源洩漏問題。

解決辦法:定義地方使用強智慧型指標,引用的地方使用弱智能指標。

#include #include using namespace std;

class b;

class a

~a()

weak_ptr_ptrb;

};class b

~b()

weak_ptr_ptra;

};int main()

結果:

沒有任何問題。成功呼叫析構函式。

又乙個問題。。

我們無法使用弱智能指標來訪問或者修改資源,,,即沒有給weak_ptr提供*和->的運算子過載函式。。。。

但是我們可以通過weak_ptr::lock()提公升為強智慧型指標來呼叫資源。

舉例**:

#include #include using namespace std;

class b;

class a

~a()

weak_ptr_ptrb;

void funa() };

class b

~b()

void funb()

weak_ptr_ptra;

};int main()

C 需要釋放資源的操作

1 通過cbitmap m bitmap cbitmap fromhandle hbitmap 返回獲取的cbitmap 物件,實際上是 cbitmap fromhandle hbitmap 在記憶體中new了乙個cbitmap 物件,所以必須在相應的地方釋放記憶體,否則會有記憶體洩露。釋放記憶體方...

c c 函式資源釋放時避免goto的方法

開發c c 模組時,因為很多記憶體資源都需要自己釋放,為了統一乙個地方釋放資源通常用goto標籤在函式退出時釋放資源,好處是資源統一釋放,不會因為在提前return時分別釋放資源導致以後修改 遺漏釋放某些資源導致死鎖或者記憶體洩漏。以下是goto模式 void goto function snpri...

C 託管程式中的資源釋放問題

第乙個就是很多人用.net寫程式,會談到託管這個概念。那麼.net所指的資源託管到底是什麼意思,是相對於所有資源,還是只限於某一方面資源?很多人對此不是很了解,其實 net 所指的託管只是針對記憶體這乙個方面,並不是對於所有的資源 因此對於 stream 資料庫的連線,gdi 的相關物件,還有 co...