1. 程式人生 > >使用C++11解決記憶體洩漏的問題

使用C++11解決記憶體洩漏的問題

    C++語言中沒有垃圾回收機制,必須自己去釋放分配的堆記憶體,否則就會記憶體洩漏。相信大部分C++開發人員都遇到過記憶體洩漏的問題,而查詢記憶體寫了的問題往往要花大量的精力。

    解決這個問題最有效的辦法就是使用智慧指標(Smart Pointer)。使用智慧指標就不用擔心這個問題了,因為智慧指標可以自動刪除分配的記憶體。智慧指標和普通指標類似,只是不需要手動釋放指標,而是通過智慧指標自己管理記憶體的釋放,這樣就不用擔心記憶體洩漏的問題了。

C++提供了三種智慧指標:std::shared_ptr ; std::uniq_ptr ; std::weak_ptr .

1. shared_ptr共享的智慧指標

Std::shared_ptr使用引用計數,每一個shared_ptr的拷貝都指向相同的記憶體。在最後一個shared_ptr析構的時候,記憶體才會被釋放。

基本用法:

初始化:
可以通過建構函式、std_make_shared輔助函式和reset方法來初始化shared_ptr:
// 建構函式初始化
Std::shared_ptr p ( new int(1) ) ;
Std::shared_ptr p2 = p ;
// 對於一個未初始化的智慧指標,可以通過reset方法來初始化。
Std::shared_ptr ptr; ptr.reset ( new int (1) ) ;
If (ptr) { cout << “ptr is not null.\n” ; }

不能將一個原始指標直接賦值給一個智慧指標:
Std::shared_ptr p = new int(1) ;   // 編譯報錯,不允許直接賦值

獲取原始指標:
通過get方法來返回原始指標
Std::shared_ptr ptr ( new int(1) ) ;
Int * p = ptr.get () ;

指標刪除器:
智慧指標初始化可以指定刪除器
Void DeleteIntPtr ( int * p ) {
delete p ;
}
Std::shared_ptr p ( new int , DeleteIntPtr ) ;
當p的引用技術為0時,自動呼叫刪除器來釋放物件的記憶體。刪除器也可以是一個lambda表示式,例如
Std::shared_ptr p ( new int , [](int * p){delete p} ) ;

注意事項:
1.不要用一個原始指標初始化多個shared_ptr。
2.不要再函式實參中建立shared_ptr,在呼叫函式之前先定義以及初始化它。
3.不要將this指標作為shared_ptr返回出來。
4.要避免迴圈引用。

2. unique_ptr 獨佔的智慧指標

Unique_ptr是一個獨佔的智慧指標,他不允許其他的智慧指標共享其內部的指標,不允許通過賦值將一個unique_ptr賦值給另外一個unique_ptr。
unique_ptr不允許複製,但可以通過函式返回給其他的unique_ptr,還可以通過std::move來轉移到其他的unique_ptr,這樣它本身就不再擁有原來指標的所有權了。
如果希望只有一個智慧指標管理資源或管理陣列就用unique_ptr,如果希望多個智慧指標管理同一個資源就用shared_ptr

3. weak_ptr弱引用的智慧指標

    弱引用的智慧指標weak_ptr是用來監視shared_ptr的,不會使引用計數加一,它不管理shared_ptr內部的指標,主要是為了監視shared_ptr的生命週期,更像是shared_ptr的一個助手。
    weak_ptr沒有過載運算子*和->,因為它不共享指標,不能操作資源,主要是為了通過shared_ptr獲得資源的監測權,它的構造不會增加引用計數,它的析構不會減少引用計數,純粹只是作為一個旁觀者來監視shared_ptr中關離得資源是否存在。
    weak_ptr還可以用來返回this指標和解決迴圈引用的問題。

相關推薦

使用C++11解決記憶體洩漏的問題

C++語言中沒有垃圾回收機制,必須自己去釋放分配的堆記憶體,否則就會記憶體洩漏。相信大部分C++開發人員都遇到過記憶體洩漏的問題,而查詢記憶體寫了的問題往往要花大量的精力。 解決這個問

[轉]Android 如何有效的解決記憶體洩漏的問題 Android 如何有效的解決記憶體洩漏的問題

Android 如何有效的解決記憶體洩漏的問題   前言:最近在研究Handler的知識,其中涉及到一個問題,如何避免Handler帶來的記憶體溢位問題。在網上找了很多資料,有很多都是互相抄的,沒有實際的作用。 本文的記憶體洩漏檢測工具是:LeakCanary &nbs

解決記憶體洩漏

一:寫p層的方法 //解耦 public void datach(){ if (shopView != null){ shopView = null; } } 二:主頁面的方法 @Override public void onDestroy() {

Android 如何有效的解決記憶體洩漏的問題

前言:最近在研究Handler的知識,其中涉及到一個問題,如何避免Handler帶來的記憶體溢位問題。在網上找了很多資料,有很多都是互相抄的,沒有實際的作用。 本文的記憶體洩漏檢測工具是:LeakCanary  github地址:https://github.com/square/le

mvp銷燬,解決記憶體洩漏

mvp銷燬,解決記憶體洩漏 //model層銷燬執行緒 public void onDestory() { if (handler != null) { handler.removeCallbacksAndMessages(null); handler = null; } } //p

Android AsyncTask 取消全部任務 , 解決記憶體洩漏問題

以下程式碼具備的功能:  1. 取消當前新增的所有 AsyncTask , 儘量減少重複的網路請求任務 (場景: 我們需要在一個介面中定時每 10s 請求一次網路獲取一次資料 ,我們知道網路請求時間是不固定的 ,可能很快的請求完成,也可能很慢,因此,我為了儘量節省開銷

_064_Android_Android 如何有效的解決記憶體洩漏的問題

轉自https://www.cnblogs.com/zhaoyanjun/p/5981386.html,感謝作者的無私分享。  Android 如何有效的解決記憶體洩漏的問題 如何避免Handler帶來的記憶體溢位問題。 本文的記憶體洩漏檢測工具是:LeakCanary &nb

檢查C++中的記憶體洩漏-通過工具來檢查

  Visual Leak Detector(VLD)是一款用於Visual C++的免費的記憶體洩露檢測工具,使用者可從下載,該軟體以庫形式與使用者的被測工程一起使用,由於VLD是按LGPL(GNU LESSER GENERAL PUBLIC LICENSE)協議對外開源,

使用 Android Studio 檢測記憶體洩漏解決記憶體洩漏問題

  本文在騰訊技術推文上 修改 釋出。     http://wetest.qq.com/lab/view/63.html?from=ads_test2_qqtips&sessionUserType=BFT.PARAMS.195040.TASKID&ADUIN=913337456&a

Handler的正確使用,使用靜態內部類+弱引用,解決記憶體洩漏,舉例說明在使用ProgressBar時的Handler類的靜態內部類實現。

       在Android中使用ProgressBar進行回撥設定進度時候會提示‘This Handler class should be static or leaks might occur’的警告,那就說明是你的自定義Handler類有記憶體洩露的問題,一般來說就是

webview api介紹+解決記憶體洩漏+js互動

1:建立webview 一般建立webview不採用在layout中直接去定義,而是用程式碼new一個webview出來,並且用RelativeLayout或LinearLayout做一個佔位. <LinearLayout android:id="@+id/wv_r

JNI程式如何檢測C程式碼的記憶體洩漏

Java呼叫C的JNI程式很容易出現記憶體洩漏問題,因為Java不負責回收C中的記憶體,所以必須自己保證C程式碼沒有記憶體洩漏問題。經過測試,memwatch就可以直接用於JNI中的C程式碼的記憶體檢測。程式在JNI呼叫後,就會在目錄下生成一個檔案,裡面記錄了記憶體資料。結論

Instruments Leak解決記憶體洩漏問題

iOS 5.0之後apple引入了Xcode編譯器特性ARC(Automatic Reference Counting,自動引用計數)來幫助開發者管理記憶體,但為了追求app的高效能與減少安裝包大小,工作中很多時候需要我們手動管理記憶體。再牛的開發者也不能保證自己寫的co

C/C++如何監測記憶體洩漏

記憶體溢位就是記憶體越界。記憶體越界有一種很常見的情況是呼叫棧溢位(即stackoverflow),雖然這種情況可以看成是棧記憶體不足的一種體現。例如:遞迴呼叫棧;比如說C/C++標準庫有個strcpy,會一直複製記憶體,直到遇到\0。; 記憶體洩漏就是記憶體申請後,用

從預設解構函式學習c++,new,delete,記憶體洩漏,野指標

預設解構函式:當系統沒有顯式定義解構函式,編譯器同樣會為物件定義一個預設解構函式,預設的解構函式只能釋放普通資料成員所佔用的空間,無法通過釋放通過new和malloc進行申請的空間,因此避免記憶體洩漏,我們要顯式的解構函式對申請的空間釋放。 記憶體洩漏(Memory Leak)是指程式中己動態分配的堆記憶體

C/C++應用程式記憶體洩漏檢查統計方案

  一、前緒   C/C++程式給某些程式設計師的幾大印象之一就是記憶體自己管理容易洩漏容易崩,筆者曾經在一個產品中使用C語言開發維護部分模組,只要產品有記憶體洩漏和崩潰的問題,就被甩鍋“我的程式是C#開發的記憶體都是託管的,C++那邊也沒有記憶體(庇護其好友),肯定是C這邊的問題”

記憶體溢位和記憶體洩漏的區別、產生原因以及解決方案【轉】

(轉自:https://www.cnblogs.com/Sharley/p/5285045.html) 記憶體溢位 out of memory,是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory;比如申請了一個integer,但給它存了long才能存下的數,那就

android 使用handle警告,,存在記憶體洩漏的危險,使用靜態內部類和弱引用的方式解決

Handle警告的原因:handle定義為內部類,會持有外部類的引用,如果外部類結束,handle因為執行耗時操作沒有結束,並持有外部類的引用,導致外部類佔用的記憶體不能釋放。 解決辦法:handle定義為靜態內部類,handle對於外部類的元件和方法的操作藉助弱引用來實現。 public

關於C++記憶體洩漏的一個經驗教訓

       近期寫了一段程式碼,發現有記憶體洩漏,經多次查詢都找不到源點,搞到焦頭爛額,最後經同事細心審查,競是粗心導致的隱藏性錯誤,為了在以後避免犯同樣的錯誤,有必有記錄下來。        在C++中記憶體管理

C++11 記憶體對齊 alignof alignas

一 現象 先看一段程式碼: struct s1 { char s; int i; }; struct s2 { int i; double d; }; cout << "-------basic type" << endl; c