C 記憶體錯誤檢測工具

2021-08-13 23:42:04 字數 3555 閱讀 3038

簡介

1)開發時,該如何盡力避免記憶體錯誤的發生;

2)開發後,該如何去確定真的沒有問題;

1)記憶體使用方式簡介;

2)使用智慧型指標降低記憶體洩露的風險;

3)windows上,使用visual studio做記憶體錯誤檢測;

4)linux上,使用valgrind做記憶體錯誤檢測;

問題引出

昨天遇到了乙個大牛,學到了不少東西。其中一些東西就是關於記憶體洩露的。對話大概是這樣的。

大牛:」你怎麼保證自己的**沒有記憶體洩露。」

我:」!@#$%^&*!(大概說的是,只要注意一點,不會出現的)」

大牛:」呵呵,你用什麼證明。」

一、記憶體使用方式簡介

1、**段:唯讀資料;

2、資料段/bss段:如果沒有顯式初始化,會被初始化為零;

3、棧空間資料:

一般指區域性變數。這類變數若未初始化,則會被賦予隨機的初值。

如果在棧中申請過大的區域性變數,會出現棧溢位。

4、堆空間資料:

出現記憶體錯誤的情況可以有兩種:

1)申請了一塊記憶體,但未釋放,俗稱記憶體洩露;

2)對於同一塊記憶體,釋放了多次;

5、其它

1)野指標:一般指未初始化或已釋放的指標。若去訪問這個指標,將出錯;

2)越界訪問:通常在使用陣列時被強調;

3)唯讀的資料和資源:如果去寫了,也就錯了;

4)訪問超出控制範圍的記憶體:比如先儲存乙個區域性變數的位址,超出它的作用域之後,又去訪問這個位址;

二、使用智慧型指標降低記憶體洩露的風險

有人說,」如果可以,盡量使用智慧型指標。」也有人說,」如果專案的大多數**都用的指標,那就別用智慧型指標,不然顯得亂。」

在可以使用智慧型指標的場景中,智慧型指標需要盡可能的替代指標的存在。

以shared_ptr為例,

type * ptr=> shared_ptrptr

new type() => make_shared()

delete ptr=> 智慧型指標會自動釋放

三、windows上,使用visual studio做記憶體錯誤檢測

當乙個觀點無法被直接證明的時候,我們可以採用旁證,即借助大家都相信的東西來間接證明。在記憶體錯誤方面,我們可以使用第三方工具來進行檢測。

在windows上,visual studio是最常用的開發工具,也可以用來檢測記憶體錯誤。它提供的功能有很多,都可以在crtdbg.h檔案中找到。

最簡單直接的一種使用方式,是將記憶體洩露的**位置列印出來。

具體方法,就是在**前加幾行**,像這樣:

#include 

#define new new(_normal_block, __file__, __line__)

static

int tmp = _crtsetdbgflag(_crtdbg_alloc_mem_df |_crtdbg_leak_check_df );

假設測試**如下:

#ifdef _msc_ver

#ifdef _debug

#include

#define new new(_normal_block, __file__, __line__)

static

int tmp = _crtsetdbgflag(_crtdbg_alloc_mem_df | _crtdbg_leak_check_df);

#endif

#endif

int main()

以debug模式編譯執行後,在輸出視窗可以看到:

detected memory leaks!

dumping objects ->

***\main.cpp(14) : normal block at

0x0102afd8, 1

bytes

long.

data: < > cd

object dump complete.

或者可以用另一種寫法,在這裡可以看到。大體上是一樣的,只是做了一些處理,方便使用。

四、linux上,使用valgrind做記憶體錯誤檢測

如果不使用第三方工具,g++本身其實也可以做很多記憶體錯誤方面的檢測工作。只需要在編譯時,加入-wall選項,它就會盡可能的列印出警告資訊。這其中就包含了很多記憶體錯誤的警告。

再回到使用第三方工具的話題。在linux上,可以使用valgrind做記憶體錯誤檢測。老樣子,先從簡單的用法開始。可以像這樣:

sudo apt-get install valgrind

valgrind --tool=memcheck --show-reachable

=yes --read-var

-info

=yes \

--verbose --time-stamp

=yes --leak-check

=full

--log

-file

=logfile.

log執行過後,我們可以再logfile.log裡檢視記憶體錯誤檢測結果。查閱時,可以先搜尋關鍵字error。這樣可以很快的定位到相關資訊,包括錯誤**位置,錯誤原因等。

上面的命令包含三個部分,即valgrind,一系列選項,可執行檔案。首先需要注意的是,這個可執行檔案是debug模式編譯的。如:

g++

-o test test.cpp -wall

-g

然後是這些選項,這裡給出的並不全,但可用。

1.-

-tool=

[default:

memcheck

]valgrind是一套工具的集合,memcheck是較為常用的乙個,作為預設選擇;2.

--show

-reachable=yes

對於控制範圍之外的記憶體洩漏也進行檢測,如全域性指標、static指標等;3.

--read

-var

-info=yes

應用程式會變慢,但是能給出更多的錯誤細節;4.

--verbose

列印更詳細的資訊;5.

--time

-stamp=yes

顧名思義,顯示時間戳;6.

--leak

-check=full

展示記憶體洩露的細節,比如在**中的位置;7.

--log-

file=logfile

.log

將valgrind的列印資訊輸出到指定檔案中,否則在直接標準輸出;

五、說明

若有興趣,可以看看下面的位址。裡面的**可以作為備用元件。

Valgrind 記憶體檢測工具

valgrind是乙個gpl的軟體,用於linux for x86,amd64 and ppc32 程式的記憶體除錯和 剖析。你可以在它的環境中執行你的程式來監視記憶體的使用情況,比如c 語言中的malloc和free或者 c 中的new和 delete。使用valgrind的工具包,你可以自動的檢...

記憶體檢測工具Valgrind

valgrind是一套linux下,開放源 gpl v2 的 除錯工具的集合。valgrind由核心 core 以及基於核心的其他除錯工具組成。核心類似於乙個框架 framework 它模擬了乙個cpu環境,並提供服務給其他工具 而其他工具則類似於外掛程式 plug in 利用核心提供的服務完成各種...

C程式記憶體洩露檢測工具

今天給大家帶來一款檢測c程式記憶體洩露的一款實用工具 memwatch memwatch 由 johan lindh 編寫,是乙個開放源 c 語言記憶體錯誤檢測工具。只要在 中新增乙個標頭檔案並在 gcc 語句中定義了 memwatch 之後,您就可以跟蹤程式中的記憶體洩漏和錯誤了。memwatch...