C语言多线程内存管理模块_第1页
C语言多线程内存管理模块_第2页
C语言多线程内存管理模块_第3页
C语言多线程内存管理模块_第4页
C语言多线程内存管理模块_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C语言多线程内存管理模块摘要:一个多线程动态内存管理模块,可以有效地检测C语言中内存泄漏和内存越界等错误。1 原理l 分配通过重新改写内存分配函数,把调用时的信息保存在一个节点中,节点中包括此内存分配的首地址,大小以及分配所在的源文件、函数、行号,并用一个HASH表来保存所有节点。l 越界检测为了检测写越界的错误,在用户申请的内存前后各增加了一定大小的内存作为监测区域,并初始化成预定值(0xdeadbeef)。如果发生越界写操作时,预定值就会发生改变, 即可检测到越界操作错误。l 释放重新改写内存释放函数free,释放时节点从HASH表中删除并进行越界检测。l 查看手动调用show_memor

2、y()或show_memory_summary()查看内存使用情况并进行越界检测。以下涉及内存分配和内存释放的函数被重新改写:1. malloc2. calloc3. realloc4. strdup5. strndup6. asprintf7. vasprintfHASH表如下图所示:节点结构如下:static struct mm_region struct mm_region *next;char file40;/* 分配所在的文件 */char func40;/* 分配所在的函数 */unsigned int lineno;/* 分配所在的行 */size_t len;/* 内存分配的大

3、小 */unsigned int fence;/* 内存起始边界,用于头越界检测 */unsigned char data0;/* 用户内存分配首地址,malloc等函数返回以此为首地址的len长度的一块内存 */ *regionsSOME_PRIME;内存中一条节点的结构:nextfilefunclinenolenfence0xdeadbeefdatafence0xdeadbeefmm_region内存起始边界检测头越界内存结束边界检测尾越界2 测试步骤:1. 引入头文件:在需要检测的C/C+文件中引入”mm.h”头文件;2. 查看内存使用情况:调用show_memory()函数查看本文件中

4、内存泄漏详细情况,或调用show_memory_summary()函数查看本文件中内存泄漏统计情况。2.1 内存泄漏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);/* 查看内存泄漏 */show_memory();show_memory_summary();return 0;2.1.2 测试结果2.2 内存越界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);/* 释放或查看内存时检测 */free(mp);return 0;2.2.2 测试结果2.3 释放错误此类错误包括:1. 释放空指针2. 释放野指针3. 重复释放4. 内存释放的起始地址与内存分配的起始地址不一致2.3.1 测试代码#include /* 加入头文件mm.h */#include mm.hint main(int

6、 argc, char *argv)char *mp = NULL;mp = (char *)malloc(6);free(mp);/* 重复释放*/free(mp);return 0;2.3.2 测试结果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等函数*/#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;/* 分配所在的函数*/unsigned int lineno;/* 分配所在的行*/size_t len;/* 内存分配的大小*/unsigned int fence;/* 内存起始边界,用于头越界检测*/unsigned char data0;/* 用户内存分配首地址,malloc等函数返回以此为首地址的len长度的一块内存*/ *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) ) /* 使用系统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);/* 内存起始标志*/reg-fence = FENCE_MAGIC;/* 内存结束标志*/fence = (unsigned int *)(ptr + reg-len); *fence =FENCE_MAGIC;pthread_mutex_lock(&mmlock);reg-next = regionshash; /* 一个hash可能对应多个值*/ 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(v

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论