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),請進(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é)點(diǎn)中,節(jié)點(diǎn)中包括此內(nèi)存分配的首地址,大小以及分配所在的源文件、函數(shù)、行號,并用一個HASH表來保存所有節(jié)點(diǎn)。l 越界檢測為了檢測寫越界的錯誤,在用戶申請的內(nèi)存前后各增加了一定大小的內(nèi)存作為監(jiān)測區(qū)域,并初始化成預(yù)定值(0xdeadbeef)。如果發(fā)生越界寫操作時,預(yù)定值就會發(fā)生改變, 即可檢測到越界操作錯誤。l 釋放重新改寫內(nèi)存釋放函數(shù)free,釋放時節(jié)點(diǎn)從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é)點(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)存起始邊界,用于頭越界檢測 */unsigned char data0;/* 用戶內(nèi)存分配首地址,malloc等函數(shù)返回以此為首地址的len長度的一塊內(nèi)存 */ *regionsSOME_PRIME;內(nèi)存中一條節(jié)點(diǎn)的結(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 <stdio.h>/* 加入頭文件mm.h */#include "mm.h"int 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;

5、2.1.2 測試結(jié)果2.2 內(nèi)存越界2.2.1 測試代碼#include <stdio.h>/* 加入頭文件mm.h */#include "mm.h"int 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

6、 測試代碼#include <stdio.h>/* 加入頭文件mm.h */#include "mm.h"int main(int 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

7、_cplusplusextern "C" #endif/* Undefine any macros */#undef malloc#undef calloc#undef 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 c

8、har *file, int lineno, const char *func);void _mm_free(void *ptr, const char *file, int lineno, 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_strndu

9、p(const char *s, size_t n, const char *file, int lineno, const char *func);int _mm_asprintf(const 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

10、own definitions */#define calloc(a,b) _mm_calloc(a,b,_FILE_, _LINE_, _PRETTY_FUNCTION_)#define 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

11、) _mm_strdup(a,_FILE_, _LINE_, _PRETTY_FUNCTION_)#define strndup(a,b) _mm_strndup(a,b,_FILE_, _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(vo

12、id);int show_memory_summary(void);#ifdef _cplusplus#endif#endif /* _MM_H_ */3.2 mm.c/* mm.c* Memory Management (from Asterisk)*/#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include "mm.h"/* 本文中不使用自定義malloc,cal

13、loc,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 struct mm_region struct mm_region *next;char file40;/* 分配所在的文件*/char func40;/* 分配所在的函數(shù)*/unsigned int lineno;/* 分配所在的行*/

14、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_PRIME)static pthread_mutex_t mmlock = PTHREAD_MUTEX_INITIALIZER;#define mm_log(.) do fprintf(stderr, _VA_ARGS_); w

15、hile (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 = (struct mm_region *)malloc(size + sizeof(*reg) + sizeof(*fence) ) /* 使用系統(tǒng)malloc */mm_log("Memory Allocation Fa

16、ilure - '%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->len = size;ptr = reg->data;hash = HASH(ptr);/* 內(nèi)存起始標(biāo)志*/r

17、eg->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 _mm_sizeof_region(void *ptr)int ha

18、sh = 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 lineno, const

19、 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

20、(&mmlock);if (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_

21、MAGIC) mm_log("WARNING: Tail fence violation at %p, in %s of %s, ""line %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

22、nmemb, size_t size, const char *file, int lineno, const char *func) void *ptr;if (ptr = _mm_alloc_region(size * nmemb, 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,

23、 func);void _mm_free(void *ptr, const char *file, int lineno, const char *func) _mm_free_region(ptr, file, lineno, func);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("W

24、ARNING: Realloc of unalloced memory at %p, in %s of %s, ""line %dn", ptr, func, file, lineno);return NULL;if (!(tmp = _mm_alloc_region(size, 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;c

25、har *_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_alloc_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 line

26、no, 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(char *)ptr, s);return (char *)ptr;int _mm_asprintf(const char *file, int lineno, const char *func, char *strp, const char *fmt, .)int siz

27、e;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 + 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

28、, 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, ap2);va_end(ap2);if (!(*strp = (char *)_mm_alloc_region(size + 1, file, lineno, func) va_end(ap);return -1;vsnprintf(*strp, size +

29、 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("nLEAK DETAIL:n");pthread_mutex_lock(&mmlock);for (x = 0; x < SOME_PRIME; x+) for (reg = regionsx; reg; reg = reg

30、->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

31、 = (unsigned 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 i

32、n %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(void)char *fn = NULL;int x;struct mm_region *reg;unsigned int len = 0;int count = 0;struct file_summary char fn80;int len;int count;struct file_summary *next; *list = NUL

溫馨提示

  • 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論