【C语言进阶深度学习记录】三十四 C语言实现内存泄漏检测模块
发布日期:2021-07-01 00:07:01
浏览次数:2
分类:技术文章
本文共 2688 字,大约阅读时间需要 8 分钟。
上一篇文章学习了malloc系列的三个函数的使用。众所周知malloc的使用很容易导致内存泄漏。本文的目的就是使用C语言来实现内存泄漏检测模块,来帮忙自动检测我们写的程序中是否出现内存泄露。
文章目录
1 内存泄露检测模块的实现原理
想要实现内存泄露检测模块,必须在内存申请的时候将申请的内存位置,在代码的哪个位置写代码申请的,以及在哪个源文件中申请的这些信息都记录下来,然后如果申请的内存没有被释放,那就最终将这些没有释放的内存的信息打印出来,我们才能够定位到内存泄露的地方。
可以采用数组记录申请的内存的信息,数组的每个元素存的是申请过的内存的信息。因为信息比较多,所以数组的元素采用结构体的形式。
采用数组的话,申请内存时遍历数组的元素,将申请的内存信息记录到数组中,释放内存的时候遍历数组查找要释放的内存信息对应哪个元素。最后还需要遍历数组查看是否数组中还残留有没有释放的内存由的话,就将泄漏的内存信息打印出来,方便查找。
1.1 各个函数模块的设计
先给出各个小部分函数的设计思想。最后给出整个代码的整合,会让你豁然开朗。可以结合后面的整个代码来看。
- 首先定义内存信息的结构体,这个结构体信息可以让我们知道申请的内存的地址,申请的代码在哪个源文件以及哪一行,以及申请的内存的字节大小。如下:
typedef struct{ void* pointer; //指针 int size; /大小 const char* file; //文件名 int line; //行号}MemoryInfo;
- 然后定义存放申请到的内存信息的结构体数组。该结构体时用于我们存放申请到的内存信息,以及在最后查找是否有内存没有释放用的:
#define SIZE 256static MemoryInfo M_array[SIZE];
- 申请内存的函数设计:标准库函数malloc无法检测内存泄漏,所以我们对malloc进行封装。在申请内存的时候,将申请到的内存信息记录到M_array数组中。参数n是代表申请多少字节内存。file代表当前在哪个源文件中使用了内存申请的函数。参数line是代表在该源文件的哪一行进行了内存申请的动作。
void* mallocEX(size_t n, const char* file, int line){ void* ret = malloc(n); if(ret!=NULL){ int i = 0; for(i=0; i
可以看到该函数中将申请到的内存信息都记录到了M_array数组中。方便后续的查询信息。
- 释放内存函数设计:释放内存的函数中,必须先遍历数组M_array ,查找要释放的内存在数组中的记录索引,在释放内存的时候,同时将数组中存放该内存的信息置空,代表该内存已经被释放:
void freeEX(void* p){ if(p!=NULL){ int i = 0; for(i=0; i
- 查询未释放的内存信息:在程序的结束,即将退出之前,需要查询当前的程序中是否有未释放的内存,如果有将该信息打印出来方便程序员定位修改。直接遍历数组M_array,只要有元素非空,说明就有内存没有被释放:
void PRINT_LEAK_INFO(){ int i = 0; printf("Potential Memory Leak Info: \n"); for(i=0; i
1.2 模块整合
上面的几个函数的设计,可以实现内存泄漏检测。将整个程序整合为下面的三个代码:
- 38-1-lyy.c
#include#include "lyy_mleak.h"void f(){ MALLOC(100); //申请内存,没有释放 }int main(){ int* p = (int*)MALLOC(3*sizeof(int)); f(); //这里发生内存泄漏 p[0] = 0; p[1] = 1; p[2] = 2; FREE(p); PRINT_LEAK_INFO(); return 0;}
- lyy_mleak.h
#ifndef _LYY_MLEAK_H#define _LYY_MLEAK_H#include#define MALLOC(n) mallocEX(n, __FILE__, __LINE__)#define FREE(p) freeEX(p)void* mallocEX(size_t n, const char* file, const int line);void freeEX(void* p);void PRINT_LEAK_INFO();#endif
- lyy_mleak.c
#include "lyy_mleak.h"#define SIZE 256typedef struct{ void* pointer; int size; const char* file; int line;}MemoryInfo;static MemoryInfo M_array[SIZE];void* mallocEX(size_t n, const char* file, int line){ void* ret = malloc(n); if(ret!=NULL){ int i = 0; for(i=0; i
- 编译运行上述代码:gcc 38-1-lyy.c lyy_mleak.c -o test.out
- ./test.out
可以看到,运行程序后,自动的为我们检测是否有未释放的内存,并且将未释放的内存信息打印出来供我们定位修改。只需要将函数f() 修改为以下即可:
void f(){ int* p = MALLOC(100); //申请内存,没有释放 ...... FREE(p);}
这样修改过后,就不会出现内存泄漏了。
2 总结
- malloc和free一定要成对出现
转载地址:https://lyy-0217.blog.csdn.net/article/details/88089266 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月23日 14时51分55秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
腾讯AI语音识别API踩坑记录
2019-04-30
安装openrave 0.9的各种依赖包
2019-05-01
@FeignClient注解的重复名称解决
2019-05-01
java.net.BindException: 无法指定被请求的地址
2019-05-01
scala list
2019-05-01
svn服务器安装
2019-05-01
spark 笔记1
2019-05-01
shell dirname basename
2019-05-01
未来已至,5G加持下的云游戏将走向何方?
2019-05-01
计算机网络 —— 网络层 1.
2019-05-01
Android生命周期
2019-05-01
Android 之 ContentProvider 与 ContentResolver
2019-05-01
【接口自动化】
2019-05-01
推荐一位川大零基础转行 Python 的人生勇士
2019-05-01
Python解惑之:True与False
2019-05-01
你要的微信小程序终于来了
2019-05-01
有了这些 Chrome 插件,效率提升10倍(建议收藏)
2019-05-01
Python 开发者都会遇到的错误:UnboundLocalError
2019-05-01
只有1%的程序员搞懂过浮点数陷阱
2019-05-01
一名 Google 工程师的大数据处理经验
2019-05-01