C語言多線程內(nèi)存管理模塊_第1頁
C語言多線程內(nèi)存管理模塊_第2頁
C語言多線程內(nèi)存管理模塊_第3頁
C語言多線程內(nèi)存管理模塊_第4頁
C語言多線程內(nèi)存管理模塊_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、C語言多線程內(nèi)存管理模塊摘要:一個(gè)多線程動(dòng)態(tài)內(nèi)存管理模塊,可以有效地檢測(cè)C語言中內(nèi)存泄漏和內(nèi)存越界等錯(cuò)誤。1 原理l 分配通過重新改寫內(nèi)存分配函數(shù),把調(diào)用時(shí)的信息保存在一個(gè)節(jié)點(diǎn)中,節(jié)點(diǎn)中包括此內(nèi)存分配的首地址,大小以及分配所在的源文件、函數(shù)、行號(hào),并用一個(gè)HASH表來保存所有節(jié)點(diǎn)。l 越界檢測(cè)為了檢測(cè)寫越界的錯(cuò)誤,在用戶申請(qǐng)的內(nèi)存前后各增加了一定大小的內(nèi)存作為監(jiān)測(cè)區(qū)域,并初始化成預(yù)定值(0xdeadbeef)。如果發(fā)生越界寫操作時(shí),預(yù)定值就會(huì)發(fā)生改變, 即可檢測(cè)到越界操作錯(cuò)誤。l 釋放重新改寫內(nèi)存釋放函數(shù)free,釋放時(shí)節(jié)點(diǎn)從HASH表中刪除并進(jìn)行越界檢測(cè)。l 查看手動(dòng)調(diào)用show_memor

2、y()或show_memory_summary()查看內(nèi)存使用情況并進(jìn)行越界檢測(cè)。以下涉及內(nèi)存分配和內(nèi)存釋放的函數(shù)被重新改寫:1. malloc2. calloc3. realloc4. strdup5. strndup6. asprintf7. vasprintfHASH表如下圖所示:節(jié)點(diǎn)結(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)存起始邊界,用于頭越界檢測(cè) */unsigned char data0;/* 用戶內(nèi)存分配首地址,malloc等函數(shù)返回以此為首地址的len長(zhǎng)度的一塊內(nèi)存 */ *regionsSOME_PRIME;內(nèi)存中一條節(jié)點(diǎn)的結(jié)構(gòu):nextfilefunclinenolenfence0xdeadbeefdatafence0xdeadbeefmm_region內(nèi)存起始邊界檢測(cè)頭越界內(nèi)存結(jié)束邊界檢測(cè)尾越界2 測(cè)試步驟:1. 引入頭文件:在需要檢測(cè)的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)計(jì)情況。2.1 內(nèi)存泄漏2.1.1 測(cè)試代碼#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 測(cè)試結(jié)果2.2 內(nèi)存越界2.2.1 測(cè)試代

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)存時(shí)檢測(cè) */free(mp);return 0;2.2.2 測(cè)試結(jié)果2.3 釋放錯(cuò)誤此類錯(cuò)誤包括:1. 釋放空指針2. 釋放野指針3. 重復(fù)釋放4. 內(nèi)存釋放的起始地址與內(nèi)存分配的起始地址不一致2.3.1 測(cè)試代碼#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 測(cè)試結(jié)果3 源碼兩個(gè)文件:”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)存起始邊界,用于頭越界檢測(cè)*/unsigned char data0;/* 用戶內(nèi)存分配首地址,malloc等函數(shù)返回以此為首地址的len長(zhǎng)度的一塊內(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; /* 一個(gè)hash可能對(duì)應(yīng)多個(gè)值*/ 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) /* 頭越界檢測(cè)*/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);/* 尾越界檢測(cè)*/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) /* 頭越界檢測(cè)*/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);/* 尾越界檢測(cè)*/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等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論