虽然市面上有很多定位内存泄露的工具,但是那都是在debug模式下面的,如果我们的代码不能再本地跑,那么这些工具对我们来说是没用的。写这篇博客的起因也是为了和大家一起商讨如果在不影响或者极少影响效率的情况下,定位到内存泄漏的问题。(本来想传到码云或者GIT’的,都他么需要验证手机号或者邮箱号,这些号码我现在都已经不再使用了,所以很尴尬,再注册一个?后面可能考虑在注册一个,现在暂时通过博客吧!)
目前写好的代码如下
#include <map>
#include <string>
#include <sstream>
#include <iostream>
using std::pair;
using std::map;
using std::string;
using std::ostringstream;
using std::cout;
using std::endl;
struct memory_info
{
string code_line;
unsigned int memory_size;
};
map<void *, memory_info> map_code_info_single;
map<void *, memory_info> map_code_info_array;
void* operator new(const unsigned int n_size, const string file_name, const int n_lines)
{
ostringstream oss;
oss << file_name << " - " << n_lines;
void* tmp = (void*)malloc(n_size);
if (NULL != tmp)
{
memory_info info_tmp;
info_tmp.code_line = oss.str();
info_tmp.memory_size = n_size;
map_code_info_single.insert(std::make_pair(tmp, info_tmp));
}
return tmp;
}
void* operator new[](const unsigned int n_size, const string file_name, const int n_lines)
{
ostringstream oss;
oss << file_name << " - " << n_lines;
void* tmp = (void*)malloc(n_size);
if (NULL != tmp)
{
memory_info info_tmp;
info_tmp.code_line = oss.str();
info_tmp.memory_size = n_size;
map_code_info_array.insert(std::make_pair(tmp, info_tmp));
}
return tmp;
}
void operator delete(void* tmp)
{
map<void *, memory_info>::iterator iter = map_code_info_single.find(tmp);
if (map_code_info_single.end() != iter)
{
map_code_info_single.erase(iter);
free(tmp);
}
}
void operator delete[](void* tmp)
{
map<void *, memory_info>::iterator iter = map_code_info_single.find(tmp);
if (map_code_info_single.end() != iter)
{
map_code_info_single.erase(iter);
free(tmp);
}
map<void *, memory_info>::iterator iter = map_code_info_array.find(tmp);
if (map_code_info_array.end() != iter)
{
map_code_info_array.erase(iter);
free(tmp);
}
}
void speak()
{
map<void *, memory_info>::iterator iter = map_code_info_single.begin();
for (; map_code_info_single.end() != iter; ++iter)
{
cout << "single_code:" << iter->second.code_line << ", memory_size:" << iter->second.memory_size << endl;
}
iter = map_code_info_array.begin();
for (; map_code_info_array.end() != iter; ++iter)
{
cout << "array_code:" << iter->second.code_line << ", memory_size:" << iter->second.memory_size << endl;
}
}
#define new new(__FILE__, __LINE__)
void main()
{
char* p_tmp = new char[100];
delete[] p_tmp;
new int[50];
speak();
}
写的不是很规范,应该提取一个类的,这里面还是有很多问题,只是说分享一下我现在的思路。
利用重载的new / new[] 和 delete / delete[] 来定位是否内存释放完全。
菜鸡一枚,只是最近遇到了这些问题,所以想写一个库来协助定位分析问题。
昨天忘记补图了,今天补上
使用了自己定义的重构函数(这里和系统的delete函数表现不一样,暂时不知道会不会有什么影响,用的时候要小心)
使用了系统的delete函数(这里系统并没有释放掉空间)
另外vld好像可以把内存泄露信息输出到文件,哎呀,尴尬了。。
修改vldint.h #define VLD_DEFAULT_REPORT_FILE_NAME L".\\memory_leak_report.txt" 这里改成自己的路径即可
修改vld.cpp m_options = VLD_OPT_REPORT_TO_FILE; 这里0x8代表是要写入文件的,另外无需在调试状态下也可以(至于其他的定义,请自行查看定义)
注:VLD采用的是目前最新的版本,其他版本可能名称和位置不一样