雖然市面上有很多定位內存泄露的工具,但是那都是在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採用的是目前最新的版本,其他版本可能名稱和位置不一樣