内存泄漏情况
对于内存泄漏我们文件来区分有2中情况
单文件/多文件
单文件
c语言
对于内存分配极少的我们可以使用自己所封装的函数,来分配/释放内存,例如m_malloc中包括了malloc和打印信息,free同理,通过打印信息一一对应的关系(打印分配的地址,还有行号),来判断是否有内存泄漏,缺点就是需要一个一个的进行对比判断,耗时。
我们需要获取的信息是有无内存泄漏的信息,我们可以在分配内存的时候在外部对应目录中创建一个文件,在释放的时候销毁这个文件,想要知道有无内存泄漏的情况,只需要查看目录中是否有文件即可,这样优化了。
根据这个思路,我们进行宏定义,将malloc替换为m_malloc
define malloc m_malloc在文件内部还是调用了malloc,但是函数已经成了我们自己实现的函数
函数中实现内存的分配,文件的创建等等。对应free实现内存的释放,文件的销毁。
对于单文件这行之有效,在文件开头将宏定义和函数的实现放入文件中即可
多文件
c语言
我们每个文件都复制粘贴显然不合适,多文件我们还可能包括第三方的库
对于多文件中我们通过hook来解决此问题,通过hook实现上面的功能就能解决,但是hook之后就会有一个问题,由于第三方库调用了malloc,如果我们在实现malloc中调用了第三方库,我们就会陷入一个递归的情况,不断的分配内存,最后段错误。
例如malloc中调用了malloc_f还调用了printf函数,而printf函数中调用了malloc。
对于这种情况是加一个标识位,例如:
//伪代码
bool enable = 1;
hook_f = dlsym(xxx);//执行hook
//别人的库实现的函数需要分配内存
void func(){
malloc();//原本执行系统的malloc,但是hook之后实现自己定义的malloc
}
//自己定义实现的malloc
void malloc(){
func();
hook_f();
}
此处就会不断的递归分配内存将malloc改为
//伪代码
void malloc(){
if(enable){
enable = 0;
func();
hook_f();
enable = 1;
}else{
hook_f();
}
}
解决了递归调用的问题。
c++语言避免内存泄漏
对于c++语言的特性,我们可以封装一个对象用来管理内存的分配和释放。
对象的构造函数中的参数设计成大小和过期时间,构造函数时构造一个线程,用于取对象中定时器中过期的内存来释放。可以参考redis中的实现。
我们还可以用只能指针来管理一个内存对象,此对象构造函数分配内存,析构函数释放内存。