C语言多线程内存管理模块(DOC)

  • 格式:doc
  • 大小:133.00 KB
  • 文档页数:16

下载文档原格式

  / 16
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C语言多线程内存管理模块

摘要:一个多线程动态内存管理模块,可以有效地检测C语言中内存泄漏和内存越界等错误。

1原理

●分配

通过重新改写内存分配函数,把调用时的信息保存在一个节点中,节点中包括此内存分配的首地址,大小以及分配所在的源文件、函数、行号,并用一个HASH表来保存所有节点。

●越界检测

为了检测写越界的错误,在用户申请的内存前后各增加了一定大小的内存作为监测区域,并初始化成预定值(0xdeadbeef)。如果发生越界写操作时,预定值就会发生改变,即可检测到越界操作错误。

●释放

重新改写内存释放函数free,释放时节点从HASH表中删除并进行越界检测。

●查看

手动调用show_memory()或show_memory_summary()查看内存使用情况并进行越界检测。

以下涉及内存分配和内存释放的函数被重新改写:

1.malloc

2.calloc

3.realloc

4.strdup

5.strndup

6.asprintf

7.vasprintf

HASH表如下图所示:

节点结构如下:

static struct mm_region

{

struct mm_region *next;

char file[40]; /* 分配所在的文件 */

char func[40]; /* 分配所在的函数 */

unsigned int lineno; /* 分配所在的行 */

size_t len; /* 内存分配的大小 */

unsigned int fence; /* 内存起始边界,用于头越界检测 */

unsigned char data[0]; /* 用户内存分配首地址,malloc等函数返回以此为首地址的len长度的一块内存 */

} *regions[SOME_PRIME];

内存中一条节点的结构:

2测试

步骤:

1.引入头文件:在需要检测的C/C++文件中引入”mm.h”头文件;

2.查看内存使用情况:调用show_memory()函数查看本文件中内存泄漏详细情况,或调用

show_memory_summary()函数查看本文件中内存泄漏统计情况。

2.1内存泄漏

2.1.1测试代码

#include

/* 加入头文件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);

/* 查看内存泄漏 */

show_memory();

show_memory_summary();

return 0;

}

2.1.2测试结果

2.2内存越界

2.2.1测试代码

#include

/* 加入头文件mm.h */

#include"mm.h"

int 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.h"

int main(int 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.1mm.h

/*

* mm.h

*

* memory usage debugging (from Asterisk)

*/

#ifndef __MM_H__

#define __MM_H__

#ifdef __cplusplus

extern "C" {

#endif

/* Undefine any macros */

#undef malloc

#undef calloc

#undef free

#undef realloc

#undef strdup

#undef strndup

#undef asprintf

#undef vasprintf

void *__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 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_strndup(const char *s, size_t n, const char *file, int lineno, const char