c++内存泄漏问题有时候很难检测。一开始处理这个问题的时候,尝试用用户操作来定位泄漏的情况,试图来减小检测范围。有时候,并没有什么峦用。
我查阅资料,希望找到简单的办法,看到大家推荐了一大堆工具。很多工具并不适合,重载new和delete确是一种简单可行的办法。
我查阅资料,希望找到简单的办法,看到大家推荐了一大堆工具。很多工具并不适合,重载new和delete确是一种简单可行的办法。
“Talk is cheap. Show me the code.”
//MemLeak.h
#ifndef __MEMLEAK_H__
#define __MEMLEAK_H__
#include <stddef.h>
#include <iostream>
#include <vector>
using namespace std;
struct MemInfo {
public:
void* ptr;
const char* file;
unsigned int line;
size_t size;
};
class MemStack {
public:
vector<MemInfo>m_vec_mem;
public:
MemStack();
~MemStack();
void Insert(void* ptr, const char* file, unsigned int line, size_t size);
void Delete(void* ptr);
void Print(void* ptr);
};
void* operator new(size_t size, const char* file, unsigned int line);
void* operator new[](size_t size, const char* file, unsigned int line);
extern MemStack mem_stack;
#define memLeakcheck_new new(__FILE__,__LINE__)
#define memLeakcheck_delete(x) do { \
mem_stack.Delete(x); \
delete (x); \
} while(0)
#define memLeakcheck_delete_array(x) do { \
mem_stack.Delete(x); \
delete[] (x); \
} while(0)
void printMemStack(void* ptr);
#endif
//MemLeak.cpp
#include "MemLeak.h"
#include<iostream>
#include <stdarg.h>
#include <string.h>
using namespace std;
MemStack mem_stack;
char memMsg[1000];
void* operator new(size_t size, const char* file, unsigned int line) {
void* ptr = malloc(size);
mem_stack.Insert(ptr, file, line, size);
return ptr;
}
void* operator new[](size_t size, const char* file, unsigned int line) {
return operator new(size, file, line);
}
void printMemStack(void* ptr)
{
mem_stack.Print(ptr);
}
MemStack::MemStack() {
m_vec_mem.clear();
}
MemStack::~MemStack() {
vector<MemInfo>().swap(m_vec_mem);
}
void MemStack::Insert(void* ptr, const char* file, unsigned int line, size_t size) {
MemInfo node;
node.ptr = ptr;
node.file = file;
node.line=line;
node.size = size;
m_vec_mem.push_back(node);
}
void MemStack::Delete(void* ptr) {
if(ptr == NULL)
return;
vector<MemInfo>::iterator itor = m_vec_mem.begin();
while(itor!=m_vec_mem.end())
{
if((*itor).ptr == ptr)
{
itor = m_vec_mem.erase(itor);
}else{
++itor;
}
}
}
void debugString(string log)
{
cout<<log<<endl;
}
void MemStack::Print(void* ptr) {
if (ptr == NULL)
{
return;
}
MemInfo *node_tep = NULL;
vector<MemInfo>::iterator itor = m_vec_mem.begin();
while(itor!=m_vec_mem.end())
{
if((*itor).ptr == ptr)
{
node_tep = &(*itor);
}
++itor;
}
if ( node_tep == NULL ){
debugString("not exist");
return;
}
size_t size = (long) ((void*)(node_tep->size));
const char* f_name = node_tep->file;
unsigned int f_line = node_tep->line;
sprintf(memMsg, "memleakcheck_debug record file: %s line: %d, size_t: %d ", f_name, f_line, size);
debugString(memMsg);
sprintf(memMsg, "memleakcheck_debug record memSize = %d\0", m_vec_mem.size());
debugString(memMsg);
}
//main.cpp
#include <iostream>
#include <vector>
#include "MemLeak.h"
using namespace std;
void Reverse(int*pa,int count);
int main(int argc, char *argv[])
{
int *ptr = memLeakcheck_new int[10];
char *ptr2 = memLeakcheck_new char[9];
memLeakcheck_delete_array(ptr2);
for( int i=0;i<mem_stack.m_vec_mem.size();++i )
{
printMemStack(mem_stack.m_vec_mem[i].ptr);
}
return 0;
}