目的:协助开发人员检查内存是否泄漏问题。
注意事项:不能直接解决开发人员的内存泄漏问题。
实现过程:将malloc和free封装起来,建链表。当调用SV_MALLOC时,向链表中插入一个结点,为结点分配内存,结点存储信息包括为该变量分配内存时所在函数名function,所在行数line,分配的字节大小size以及地址ptr。当调用SV_FREE时,从链表中找到先前malloc的指针变量,将该结点信息从链表中删除并释放该结点的内存空间。
涉及知识:结构体,指针,链表,动态分配内存,封装函数的宏定义小技巧。
先放上代码,抽空再讲吧
#ifndef _TEST_MEM_H_
#define _TEST_MEM_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
/* 用于输出链表的函数 */
void display();
void *sv_malloc(size_t size, char *function, int line);
void sv_free(void *ptr, char *function, int line);
void mem_check_init();
#define SV_MALLOC(size) sv_malloc((size), __FUNCTION__, __LINE__)
#define SV_FREE(ptr) sv_free(ptr, __FUNCTION__, __LINE__);
#endif
#include <test_mem.h>
#include "stdio.h"
#include "stdlib.h"
//定义结构体变量类型Elem
typedef struct
{
char *function;
int line;
int size;
char *ptr;
}Elem;
//链表中结点的结构
typedef struct Link
{
Elem elem;
struct Link *next;
}link;
//定义未释放内存链表头节点
link *link_list = NULL;
Elem *mem_in;
int mem_in_id;
/**< 初始化链表的函数 */
link * initLink();
/**< p为原链表,elem表示新数据元素,insert_position_number表示新元素要插入的位置 */
link * insertElem(link *p, Elem elem, int insert_position_number);
/**< 删除结点的函数,p代表操作链表,insert_position_number代表删除节点的位置 */
link * deleteElem(link *p, int insert_position_number);
/**< 查找结点的函数,elem为目标结点的数据域的值,查找到元素并删除 */
int selectElemAndDelete(link