記憶體洩露檢測詳細分析

2021-06-04 15:13:22 字數 2319 閱讀 4578

詳細分析記憶體洩露檢測

一般我們常說的記憶體洩漏是指堆記憶體的洩漏。堆記憶體是指程式從堆中分配的,使用完後必須顯式釋放的記憶體。c++中使用new和new實現從堆中分配到一塊記憶體,使用完後,程式必須負責相應的呼叫delete或delete釋放該記憶體塊,否則,這塊記憶體就不能被再次使用,我們就說這塊記憶體洩漏了。

下面4種記憶體洩露分類概括了常見的絕大部分的記憶體洩露的情形。

1. 常發性記憶體洩漏。發生記憶體洩漏的**會被多次執行到,每次被執行的時候都會導致一塊記憶體洩漏。

2. 偶發性記憶體洩漏。發生記憶體洩漏的**只有在某些特定環境或操作過程下才會發生。常發性和偶發性是相對的。

3. 一次性記憶體洩漏。發生記憶體洩漏的**只會被執行一次,或者由於演算法上的缺陷,導致總會有一塊且僅一塊記憶體發生洩漏。

4. 隱式記憶體洩漏。程式在執行過程中不停的分配記憶體,但是直到結束的時候才釋放記憶體。嚴格的說這裡並沒有發生記憶體洩漏,因為最終程式釋放了所有申請的記憶體。但是對於乙個伺服器程式,需要執行幾天,幾周甚至幾個月,不及時釋放記憶體也可能導致最終耗盡系統的所有記憶體。所以,我們稱這類記憶體洩漏為隱式記憶體洩漏。

c++中通過new 和 delete來獲得、釋放記憶體。在了解記憶體洩露檢測原理前,我們可以先要明白c++中new和delete的工作原理。這首先要了解new 和 delete工作過程。

new operator

一般而言,我們在寫c++程式的時候,通過呼叫乙個簡單的關鍵字new就獲得了對應的記憶體,以至於我們認為他就是c語言中malloc的別名。但事實上,c++中呼叫new有如下三個必須的動作:

1)    獲取需要申請的記憶體大小

2)    呼叫operator new的對應形式,獲得一塊裸(raw)記憶體。

3)    如果有建構函式,則呼叫對應的建構函式進行記憶體初始化。

c++中六種重構形式,分別對應如下:

void *operator new(std::size_t count throw(std::bad_alloc);   //預設版本        

void *operator new(std::size_t count, const std::nothrow_t&) throw();

void *operator new(std::size_t count, void *ptr) throw();

//這是於我們用於重構的版本,有附加引數

void *operator new(std::size_t count)  throw(std::bad_alloc);

void *operator new(std::size_t count,  const std::nothrow_t&) throw();

void *operator new(std::size_t count, void *ptr) throw();

operator delete也有2種重構形式,分別如下:

void operator delete(void *);

void operator delete(void *);

這裡順便談一下new、new  delete、delete之間的區別於連續 

其中 operator new 和operator delete 是通過呼叫operator new和operator delete來實現的,而且完全一樣(就是說所分配、釋放記憶體時的動作完全一樣)。

但別忘了newoperator實際執行的過程中,順序是如下的:

1.首呼叫 operator new來申請記憶體。

2.呼叫物件的建構函式。

3.利用構造的物件初始化這片記憶體。

可以想象operator new 的過程和這一樣,只是分配的記憶體大小、生成物件的數目(呼叫建構函式次數)的區別罷了。

operator delete的過程就是相當於 new operator的倒轉。

1.呼叫物件的析構函式

2.釋放記憶體

所以到這裡應該就可以猜出,delete與delete之間的區別了:呼叫析構函式的次數(delete 只會呼叫第乙個物件的析構函式,而delete會呼叫所有物件的析構函式)。假如物件本身沒有析構函式(比如只是基本型別的話),delete和delete的效果都是一樣的,但肯定不推薦這麼用,因為這至少讓人很費解。

記憶體洩露的原理到時比較簡單:

1.首先定義重構版本的operator new new;  operator delete operator delete;這裡進行記憶體申請、釋放的管理,這樣就可以知道了那裡記憶體發生了洩露。

2.定義二個巨集  define debug_new new(_file_, _line_)(將new轉向為我們重構過的new) define new debug_new(這個是控制開關,那裡需要檢測,就在哪個.cpp檔案中定義這個巨集)

const詳細分析

最近在分析 linux 驅動的過程過程中遇到一些關於 const 的使用,現在在這裡詳細剖析一下 一,const int p 首先分析一下幾個概念 1 p 是乙個指標變數,因而它也是乙個變數,所謂變數就有變數的位址和變數的值,而這裡 p變數的值就是乙個位址,該位址下存放的是乙個整數,p的值等於這個整...

約數詳細分析

約數詳細分析 我們先來認識一下約數 約數分正約數和負約數兩種,我們一般只討論正約數。也就是說,接下來所提的約數,只考慮正約數。如果有乙個數k,滿足k n,那麼k就是n 的約數 因數 n是k的倍數。求乙個數的約數是資訊學競賽裡乙個基礎的不能再基礎的問題。如果只求乙個數,最容易想到的就是列舉。當然列舉也...

vue cli 詳細分析

vue lic 是 vue 官方提供的腳手架工具,預設搭建好乙個專案的基本架子,我們只需要在此基礎上進行相應的修改即可。注意 安裝 vue cli 前需要事先配置好 node 環境 npm install g vue cli 如果是 mac 電 sudo表示以管理員的許可權 sudo install...