




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、C語言多線程內(nèi)存管理模塊摘要:一個多線程動態(tài)內(nèi)存管理模塊,可以有效地檢測C語言中內(nèi)存泄漏和內(nèi)存越界等錯誤。1 原理l 分配通過重新改寫內(nèi)存分配函數(shù),把調(diào)用時的信息保存在一個節(jié)點中,節(jié)點中包括此內(nèi)存分配的首地址,大小以及分配所在的源文件、函數(shù)、行號,并用一個HASH表來保存所有節(jié)點。l 越界檢測為了檢測寫越界的錯誤,在用戶申請的內(nèi)存前后各增加了一定大小的內(nèi)存作為監(jiān)測區(qū)域,并初始化成預(yù)定值(0xdeadbeef)。如果發(fā)生越界寫操作時,預(yù)定值就會發(fā)生改變, 即可檢測到越界操作錯誤。l 釋放重新改寫內(nèi)存釋放函數(shù)free,釋放時節(jié)點從HASH表中刪除并進(jìn)行越界檢測。l 查看手動調(diào)用show_memor
2、y()或show_memory_summary()查看內(nèi)存使用情況并進(jìn)行越界檢測。以下涉及內(nèi)存分配和內(nèi)存釋放的函數(shù)被重新改寫:1. malloc2. calloc3. realloc4. strdup5. strndup6. asprintf7. vasprintfHASH表如下圖所示:節(jié)點結(jié)構(gòu)如下:static struct mm_region struct mm_region *next;char file40;/* 分配所在的文件 */char func40;/* 分配所在的函數(shù) */unsigned int lineno;/* 分配所在的行 */size_t len;/* 內(nèi)存分配的大
3、小 */unsigned int fence;/* 內(nèi)存起始邊界,用于頭越界檢測 */unsigned char data0;/* 用戶內(nèi)存分配首地址,malloc等函數(shù)返回以此為首地址的len長度的一塊內(nèi)存 */ *regionsSOME_PRIME;內(nèi)存中一條節(jié)點的結(jié)構(gòu):nextfilefunclinenolenfence0xdeadbeefdatafence0xdeadbeefmm_region內(nèi)存起始邊界檢測頭越界內(nèi)存結(jié)束邊界檢測尾越界2 測試步驟:1. 引入頭文件:在需要檢測的C/C+文件中引入”mm.h”頭文件;2. 查看內(nèi)存使用情況:調(diào)用show_memory()函數(shù)查看本文件中
4、內(nèi)存泄漏詳細(xì)情況,或調(diào)用show_memory_summary()函數(shù)查看本文件中內(nèi)存泄漏統(tǒng)計情況。2.1 內(nèi)存泄漏2.1.1 測試代碼#include /* 加入頭文件mm.h */#include mm.hint main(int argc, char *argv)char *mp = NULL;char *cp = NULL;mp = (char *)malloc(6);cp = (char *)calloc(1,10);/* 查看內(nèi)存泄漏 */show_memory();show_memory_summary();return 0;2.1.2 測試結(jié)果2.2 內(nèi)存越界2.2.1 測試代
5、碼#include /* 加入頭文件mm.h */#include mm.hint main(int argc, char *argv)char *mp = NULL;mp = (char *)malloc(6);/* 越界操作 */memset(mp,0, 10);/* 釋放或查看內(nèi)存時檢測 */free(mp);return 0;2.2.2 測試結(jié)果2.3 釋放錯誤此類錯誤包括:1. 釋放空指針2. 釋放野指針3. 重復(fù)釋放4. 內(nèi)存釋放的起始地址與內(nèi)存分配的起始地址不一致2.3.1 測試代碼#include /* 加入頭文件mm.h */#include mm.hint main(int
6、 argc, char *argv)char *mp = NULL;mp = (char *)malloc(6);free(mp);/* 重復(fù)釋放*/free(mp);return 0;2.3.2 測試結(jié)果3 源碼兩個文件:”mm.h”和“mm.c”3.1 mm.h/* * mm.h* memory usage debugging (from Asterisk)*/#ifndef _MM_H_#define _MM_H_#ifdef _cplusplusextern C #endif/* Undefine any macros */#undef malloc#undef calloc#unde
7、f free#undef realloc#undef strdup#undef strndup#undef asprintf#undef vasprintfvoid *_mm_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func);void *_mm_malloc(size_t size, const char *file, int lineno, const char *func);void _mm_free(void *ptr, const char *file, int linen
8、o, const char *func);void *_mm_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func);char *_mm_strdup(const char *s, const char *file, int lineno, const char *func);char *_mm_strndup(const char *s, size_t n, const char *file, int lineno, const char *func);int _mm_asprintf(c
9、onst char *file, int lineno, const char *func, char *strp, const char *format, .);int _mm_vasprintf(char *strp, const char *format, va_list ap, const char *file, int lineno, const char *func);/* Provide our own definitions */#define calloc(a,b) _mm_calloc(a,b,_FILE_, _LINE_, _PRETTY_FUNCTION_)#defin
10、e malloc(a) _mm_malloc(a,_FILE_, _LINE_, _PRETTY_FUNCTION_)#define free(a) _mm_free(a,_FILE_, _LINE_, _PRETTY_FUNCTION_)#define realloc(a,b) _mm_realloc(a,b,_FILE_, _LINE_, _PRETTY_FUNCTION_)#define strdup(a) _mm_strdup(a,_FILE_, _LINE_, _PRETTY_FUNCTION_)#define strndup(a,b) _mm_strndup(a,b,_FILE_,
11、 _LINE_, _PRETTY_FUNCTION_)#define asprintf(a, b, c.) _mm_asprintf(_FILE_, _LINE_, _PRETTY_FUNCTION_, a, b, c)#define vasprintf(a,b,c) _mm_vasprintf(a,b,c,_FILE_, _LINE_, _PRETTY_FUNCTION_)int show_memory(void);int show_memory_summary(void);#ifdef _cplusplus#endif#endif /* _MM_H_ */3.2 mm.c/* mm.c*
12、Memory Management (from Asterisk)*/#include #include #include #include #include #include mm.h/* 本文中不使用自定義malloc,calloc,free等函數(shù)*/#undef malloc#undef calloc#undef realloc#undef strdup#undef strndup#undef free#undef vasprintf#undef asprintf#define SOME_PRIME 563#define FENCE_MAGIC 0xdeadbeefstatic stru
13、ct mm_region struct mm_region *next;char file40;/* 分配所在的文件*/char func40;/* 分配所在的函數(shù)*/unsigned int lineno;/* 分配所在的行*/size_t len;/* 內(nèi)存分配的大小*/unsigned int fence;/* 內(nèi)存起始邊界,用于頭越界檢測*/unsigned char data0;/* 用戶內(nèi)存分配首地址,malloc等函數(shù)返回以此為首地址的len長度的一塊內(nèi)存*/ *regionsSOME_PRIME;#define HASH(a) (unsigned long)(a) % SOME
14、_PRIME)static pthread_mutex_t mmlock = PTHREAD_MUTEX_INITIALIZER;#define mm_log(.) do fprintf(stderr, _VA_ARGS_); while (0)static inline void *_mm_alloc_region(size_t size, const char *file, int lineno, const char *func)struct mm_region *reg;void *ptr = NULL;unsigned int *fence;int hash;if (!(reg =
15、(struct mm_region *)malloc(size + sizeof(*reg) + sizeof(*fence) ) /* 使用系統(tǒng)malloc */mm_log(Memory Allocation Failure - %d bytes in function %s at line %d of %sn, (int) size, func, lineno, file);strncpy(reg-file, file, sizeof(reg-file);strncpy(reg-func, func, sizeof(reg-func);reg-lineno = lineno;reg-le
16、n = size;ptr = reg-data;hash = HASH(ptr);/* 內(nèi)存起始標(biāo)志*/reg-fence = FENCE_MAGIC;/* 內(nèi)存結(jié)束標(biāo)志*/fence = (unsigned int *)(ptr + reg-len); *fence =FENCE_MAGIC;pthread_mutex_lock(&mmlock);reg-next = regionshash; /* 一個hash可能對應(yīng)多個值*/ regionshash = reg;pthread_mutex_unlock(&mmlock);return ptr;static inline size_t _
17、mm_sizeof_region(void *ptr)int hash = HASH(ptr);struct mm_region *reg;size_t len = 0;pthread_mutex_lock(&mmlock);for (reg = regionshash; reg; reg = reg-next) if (reg-data = ptr) len = reg-len;break;pthread_mutex_unlock(&mmlock);return len;static void _mm_free_region(void *ptr, const char *file, int
18、lineno, const char *func)int hash = HASH(ptr);struct mm_region *reg, *prev = NULL;unsigned int *fence;pthread_mutex_lock(&mmlock);for (reg = regionshash; reg; reg = reg-next) if (reg-data = ptr) if (prev)prev-next = reg-next;elseregionshash = reg-next;break;prev = reg;pthread_mutex_unlock(&mmlock);i
19、f (reg) /* 頭越界檢測*/if (reg-fence != FENCE_MAGIC) mm_log(WARNING: Head fence violation at %p, in %s of %s, line %dn, reg-data, reg-func, reg-file, reg-lineno);/* 尾越界檢測*/fence = (unsigned int *)(reg-data + reg-len);if ( *fence != FENCE_MAGIC) mm_log(WARNING: Tail fence violation at %p, in %s of %s, lin
20、e %dn, reg-data, reg-func, reg-file, reg-lineno);free(reg); else mm_log(WARNING: Freeing unused memory at %p, in %s of %s, line %dn,ptr, func, file, lineno);void *_mm_calloc(size_t nmemb, size_t size, const char *file, int lineno, const char *func) void *ptr;if (ptr = _mm_alloc_region(size * nmemb,
21、file, lineno, func) memset(ptr, 0, size * nmemb);return ptr;void *_mm_malloc(size_t size, const char *file, int lineno, const char *func) return _mm_alloc_region(size, file, lineno, func);void _mm_free(void *ptr, const char *file, int lineno, const char *func) _mm_free_region(ptr, file, lineno, func
22、);void *_mm_realloc(void *ptr, size_t size, const char *file, int lineno, const char *func) void *tmp;size_t len = 0;if (ptr & !(len = _mm_sizeof_region(ptr) mm_log(WARNING: Realloc of unalloced memory at %p, in %s of %s, line %dn, ptr, func, file, lineno);return NULL;if (!(tmp = _mm_alloc_region(si
23、ze, file, lineno, func)return NULL;if (len size)len = size;if (ptr) memcpy(tmp, ptr, len);_mm_free_region(ptr, file, lineno, func);return tmp;char *_mm_strdup(const char *s, const char *file, int lineno, const char *func) size_t len;void *ptr;if (!s)return NULL;len = strlen(s) + 1;if (ptr = _mm_allo
24、c_region(len, file, lineno, func)strcpy(char *)ptr, s);return (char *)ptr;char *_mm_strndup(const char *s, size_t n, const char *file, int lineno, const char *func) size_t len;void *ptr;if (!s)return NULL;len = strlen(s) + 1;if (len n)len = n;if (ptr = _mm_alloc_region(len, file, lineno, func)strcpy
25、(char *)ptr, s);return (char *)ptr;int _mm_asprintf(const char *file, int lineno, const char *func, char *strp, const char *fmt, .)int size;va_list ap, ap2;char s;*strp = NULL;va_start(ap, fmt);va_copy(ap2, ap);size = vsnprintf(&s, 1, fmt, ap2);va_end(ap2);if (!(*strp = (char *)_mm_alloc_region(size
26、 + 1, file, lineno, func) va_end(ap);return -1;vsnprintf(*strp, size + 1, fmt, ap);va_end(ap);return size;int _mm_vasprintf(char *strp, const char *fmt, va_list ap, const char *file, int lineno, const char *func) int size;va_list ap2;char s;*strp = NULL;va_copy(ap2, ap);size = vsnprintf(&s, 1, fmt,
27、ap2);va_end(ap2);if (!(*strp = (char *)_mm_alloc_region(size + 1, file, lineno, func) va_end(ap);return -1;vsnprintf(*strp, size + 1, fmt, ap);return size;int show_memory(void)char *fn = NULL;struct mm_region *reg;unsigned int x;unsigned int len = 0;unsigned int count = 0;unsigned int *fence;mm_log(
28、nLEAK DETAIL:n);pthread_mutex_lock(&mmlock);for (x = 0; x next) if (!fn | !strcasecmp(fn, reg-file) | !strcasecmp(fn, anomolies) /* 頭越界檢測*/if (reg-fence != FENCE_MAGIC) mm_log(WARNING: Head fence violation at %p, in %s of %s, line %dn, reg-data, reg-func, reg-file, reg-lineno);/* 尾越界檢測*/fence = (uns
29、igned int *)(reg-data + reg-len);if ( *fence != FENCE_MAGIC) mm_log(WARNING: Tail fence violation at %p, in %s of %s, line %dn, reg-data, reg-func, reg-file, reg-lineno);if (!fn | !strcasecmp(fn, reg-file) mm_log(%10d bytes allocated in %20s at line %5d of %sn, (int) reg-len, reg-func, reg-lineno, reg-file);len += reg-len;count+;pthread_mutex_unlock(&mmlock);mm_log(%d bytes allocated in %d allocationsn, len, count);return 0;int show_memory_summary
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 拓寬項目管理考試視野的學(xué)習(xí)方式試題及答案
- 金岳霖課題申報書
- 課題預(yù)算申報書范本
- 證券從業(yè)資格證特殊證券知識試題及答案
- 土建科技課題申報書
- 人教版七年級音樂下冊(簡譜)第5單元《桑塔·露琪亞》教學(xué)設(shè)計
- 2025年中國微型收割機市場調(diào)查研究報告
- 注冊會計師團隊作業(yè)實務(wù)試題及答案
- 系統(tǒng)規(guī)劃2025年證券從業(yè)資格證考試備考試題及答案
- 2025年財務(wù)行業(yè)的創(chuàng)新與實踐探索試題及答案
- GB/T 14713-2009旋切機通用技術(shù)條件
- 低成本自動化的開展與案例課件
- 不予受理反訴民事上訴狀(標(biāo)準(zhǔn)版)
- 高中英語語法之虛擬語氣(課件3份)
- 粵教版2022年小學(xué)六年級科學(xué)下冊期中測試試卷及答案2022-2023
- 北師大六年級下冊數(shù)學(xué)第三單元《圖形的運動》教學(xué)設(shè)計
- 國際石油合作主要合同模式課件
- 橋梁加固改造工程施工質(zhì)量管理體系與措施
- 第二十六章慢性腎小球腎炎演示文稿
- 設(shè)施設(shè)備維修記錄表
- 自動化設(shè)備檢修規(guī)程
評論
0/150
提交評論