C語言記憶體洩漏檢測方法

2021-08-15 00:16:43 字數 4349 閱讀 7591

記憶體洩漏是c語言程式設計中乙個很常見的問題,而且由於記憶體洩漏所導致的問題出現較緩慢,所以不容易覺察,所以寫乙個簡單的程式來檢測記憶體洩漏很有必要。

記憶體洩漏通常是指堆記憶體的洩漏,也就是通過malloc、calloc函式申請的記憶體,因此記憶體洩漏的檢測方法核心思想就是通過巨集定義自定義記憶體分配及釋放函式來替換使用者的malloc、calloc、free等函式。設計資料結構記錄記憶體申請資訊,申請記憶體時,記錄並插入到全域性的鍊錶中;釋放記憶體時從全域性鍊錶中查詢對應的記錄,並刪除。程式結束時,將鍊錶中資訊寫入檔案,並清除鍊錶。

如下所示,通過巨集定義替換malloc、calloc、free等函式,並插入__file__、__line__定位語句位置。

[cpp]view plain

copy

print

? #define malloc(size) malloc_detector(size,__file__,__line__)

#define calloc(element_num,element_size) calloc_detector (element_num,element_size,__file__,__line__)

#define free(addr) free_detector(addr)

設計記憶體申請資訊如下所示:  

typedef

struct __infoalloc_info;  

typedef

struct __nodealloc_info_node,*alloc_info_list;  

#define malloc(size) malloc_detector(size,__file__,__line__)

#define calloc(element_num,element_size) calloc_detector (element_num,element_size,__file__,__line__)

#define free(addr) free_detector(addr)

設計記憶體申請資訊如下所示:

typedef struct __infoalloc_info;

typedef struct __nodealloc_info_node,*alloc_info_list;

最終資訊被寫入到檔案output_file中,以「w+」模式開啟檔案

[cpp]view plain

copy

print

? #define output_file "leak_detector_report.txt"

#define output_file "leak_detector_report.txt"

在定義被替換的malloc等函式之前,必須通過undef語句將malloc等的巨集定義取消,以防止出現死迴圈的問題,然後才可以定義替換函式

[cpp]view plain

copy

print

? #undef malloc

#undef calloc

#undef free

malloc_detector、free_detector定義如以下**所示。  

void *malloc_detector(size_t size,unsigned char *file,unsigned int line)  

void free_detector(void *addr)    

#undef malloc

#undef calloc

#undef free

malloc_detector、free_detector定義如以下**所示。

void *malloc_detector(size_t size,unsigned char *file,unsigned int line)

void free_detector(void *addr)

程式結束時刻呼叫report_info函式儲存檢測資訊。

[cpp]view plain

copy

print

? void report_info()  

char info[sizeof(alloc_info)+128];  

alloc_info_list i=head,pre;  

if(i==null)  

for(i=head;i!=null;)  

flcose(fp_write);  

}  

void report_info()

char info[sizeof(alloc_info)+128];

alloc_info_list i=head,pre;

if(i==null)

for(i=head;i!=null;)

flcose(fp_write);

}

以下兩個函式為鍊錶操作

[cpp]view plain

copy

print

? void add_info(alloc_info info); //add memory alloc info to alloc_info_list

void delete_info(void *addr);   //find and delete the alloc info     

void add_info(alloc_info info); //add memory alloc info to alloc_info_list

void delete_info(void *addr); //find and delete the alloc info

測試程式如下:

[cpp]view plain

copy

print

? #define debug

#include

#include

#include"leak_detector_c.h"

extern alloc_info_list head;  

int main()    

#define debug

#include#include#include"leak_detector_c.h"

extern alloc_info_list head;

int main()

測試結果如下:

[cpp]view plain

copy

print

? memory leak:file f:\個人原始碼庫\記憶體洩漏處理方法\leak_detctor_c_v2\text.c line 9,addr 32620,size 101  

memory leak:file f:\個人原始碼庫\記憶體洩漏處理方法\leak_detctor_c_v2\text.c line 10,addr 32728,size 102  

memory leak:file f:\個人原始碼庫\記憶體洩漏處理方法\leak_detctor_c_v2\text.c line 12,addr 32830,size 103  

memory leak:file f:\個人原始碼庫\記憶體洩漏處理方法\leak_detctor_c_v2\text.c line 13,addr 33ad0,size 104  

memory leak:file f:\個人原始碼庫\記憶體洩漏處理方法\leak_detctor_c_v2\text.c line 9,addr 32620,size 101

memory leak:file f:\個人原始碼庫\記憶體洩漏處理方法\leak_detctor_c_v2\text.c line 10,addr 32728,size 102

memory leak:file f:\個人原始碼庫\記憶體洩漏處理方法\leak_detctor_c_v2\text.c line 12,addr 32830,size 103

memory leak:file f:\個人原始碼庫\記憶體洩漏處理方法\leak_detctor_c_v2\text.c line 13,addr 33ad0,size 104

檢測記憶體洩漏時,預設每乙個free所對應的位址已經被申請,即已經儲存在全域性列表中,可以對刪除函式進行擴充,如果搜尋完整個列表都沒有發現對應的alloc_info則可以判定為free出錯,對於定位free error有幫助。

**:

C 記憶體洩漏檢測方法

原文參考引用自部落格 c 中的記憶體洩露一般指堆中的記憶體洩露。堆記憶體是我們手動malloc realloc new申請的,程式不會自動 需要呼叫free或delete手動釋放,否則就會造成記憶體洩露。記憶體洩露其實還應該包括系統資料的洩露,比如socket連線等,使用完後也要釋放。記憶體洩露的原...

C 記憶體洩漏檢測

include stdafx.h ifdef debug define debug new new normal block,file line 重新定義new用於記憶體洩漏檢測時輸出行號 define debug malloc s malloc dbg s,normal block,file li...

C 記憶體洩漏檢測

今天寫乙個程式突然想檢測一下是否有記憶體洩漏,於是上網查了一下,大多數都是一種方法。只是實現略有不同,記錄如下。在你想檢測的地方都必須包含 define crtdbg map alloc include include 在程式末尾加上 crtdumpmemoryleaks debug除錯後,如果有記...