东营网站seo顾问,有哪些网站做的比较好的,中型网站每天访问量,济南seo整站外包上一篇文章学习了malloc系列的三个函数的使用。众所周知malloc的使用很容易导致内存泄漏。本文的目的就是使用C语言来实现内存泄漏检测模块#xff0c;来帮忙自动检测我们写的程序中是否出现内存泄露。 文章目录1 内存泄露检测模块的实现原理1.1 各个函数模块的设计1.2 模块整… 上一篇文章学习了malloc系列的三个函数的使用。众所周知malloc的使用很容易导致内存泄漏。本文的目的就是使用C语言来实现内存泄漏检测模块来帮忙自动检测我们写的程序中是否出现内存泄露。 文章目录1 内存泄露检测模块的实现原理1.1 各个函数模块的设计1.2 模块整合2 总结 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(i0; iSIZE; i){if(M_array[i].pointerNULL){M_array[i].pointer ret;M_array[i].size n;M_array[i].file file;M_array[i].line line;break;}}}return ret;
}可以看到该函数中将申请到的内存信息都记录到了M_array数组中。方便后续的查询信息。 释放内存函数设计释放内存的函数中必须先遍历数组M_array 查找要释放的内存在数组中的记录索引在释放内存的时候同时将数组中存放该内存的信息置空代表该内存已经被释放
void freeEX(void* p){if(p!NULL){int i 0;for(i0; iSIZE; i){if(M_array[i].pointer p){M_array[i].pointer NULL;M_array[i].size 0;M_array[i].file NULL;M_array[i].line 0;free(p);break;} }}
}查询未释放的内存信息在程序的结束即将退出之前需要查询当前的程序中是否有未释放的内存如果有将该信息打印出来方便程序员定位修改。直接遍历数组M_array,只要有元素非空说明就有内存没有被释放
void PRINT_LEAK_INFO(){int i 0;printf(Potential Memory Leak Info: \n);for(i0; iSIZE; i){if(M_array[i].pointer ! NULL){printf(Address: %p, size:%d, Location: %s:%d\n, M_array[i].pointer, M_array[i].size, M_array[i].file, M_array[i].line);}}
}1.2 模块整合
上面的几个函数的设计可以实现内存泄漏检测。将整个程序整合为下面的三个代码
38-1-lyy.c
#include stdio.h
#include lyy_mleak.hvoid 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 malloc.h#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();#endiflyy_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(i0; iSIZE; i){if(M_array[i].pointerNULL){M_array[i].pointer ret;M_array[i].size n;M_array[i].file file;M_array[i].line line;break;}}}return ret;
}void freeEX(void* p){if(p!NULL){int i 0;for(i0; iSIZE; i){if(M_array[i].pointer p){M_array[i].pointer NULL;M_array[i].size 0;M_array[i].file NULL;M_array[i].line 0;free(p);break;} }}
}void PRINT_LEAK_INFO(){int i 0;printf(Potential Memory Leak Info: \n);for(i0; iSIZE; i){if(M_array[i].pointer ! NULL){printf(Address: %p, size:%d, Location: %s:%d\n, M_array[i].pointer, M_array[i].size, M_array[i].file, M_array[i].line);}}
}编译运行上述代码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一定要成对出现