一、Windows平台
CRT、LVD库
使用 CRT 库查找内存泄漏 - Visual Studio (Windows) | Microsoft Learn
二、Linux平台
valgrind库
algrind --leak-check=yes ./xxx
如果线上有内存泄漏:
无法解决,只有用一些前置工作进行处理
如果内存泄漏:
1.对malloc进行hook
三、动态内存检测
直接上代码:
main.cpp
#include "NewDebug.h"
#include <iostream>
using namespace std;
void main() {
auto a = new int(4);
}
NewDebug.h
#ifndef DEBUG_NEW_H_
#define DEBUG_NEW_H_
#ifndef NDEBUG
#include "TracerNew.h"
void* operator new(size_t size, const char* file, long line);
#define new new(__FILE__, __LINE__)
#endif // !NDEBUG
#endif
TracerNew.h
#ifndef TRACER_NEW_H_
#define TRACER_NEW_H_
#ifndef NDEBUG
#include <map>
void* operator new(size_t size, const char* file, long line);
void operator delete(void* p);
class TracerNew {
class TracerNewInfo {
public:
TracerNewInfo(const char *file = nullptr, long line = 0);
const char* File() const;
long Line() const;
private:
const char* file_;
long line_;
};
class Lock {
public:
Lock(TracerNew& tracer):tracer_(tracer) {
tracer.lock_count_++;
}
~Lock() {
tracer_.lock_count_--;
}
private:
TracerNew& tracer_;
};
public:
static bool Ready;
TracerNew();
~TracerNew();
void Add(void* p, const char* file, long line);
void Remove(void *p);
void Dump();
private:
std::map<void*, TracerNewInfo> tracer_infos_;
long lock_count_;
};
#endif // !NDEBUG
#endif // ! TRACER_NEW_H_
TracerNew.cpp
#include "TracerNew.h"
#ifndef NDEBUG
#include <cstdlib>
#include <iostream>
TracerNew NewTracer;
bool TracerNew::Ready = false;
void* operator new(size_t size, const char* file, long line) {
void* p = malloc(size);
if (TracerNew::Ready)
NewTracer.Add(p, file, line);
return p;
}
void operator delete(void* p) {
if (TracerNew::Ready) {
NewTracer.Remove(p); //delete时候,NewTracer已经释放了,再remove导致程序崩溃
}
free(p);
}
TracerNew::TracerNewInfo::TracerNewInfo(const char* file, long line):file_(file), line_(line) {
}
const char* TracerNew::TracerNewInfo::File() const {
return file_;
}
long TracerNew::TracerNewInfo::Line() const {
return line_;
}
TracerNew::TracerNew() {
TracerNew::Ready = 1;
}
TracerNew::~TracerNew() {
Ready = false;
Dump();
}
void TracerNew::Add(void* p, const char* file, long line) {
if (lock_count_ > 0)
return;
Lock lock(*this);
tracer_infos_[p] = TracerNewInfo(file, line);
}
void TracerNew::Remove(void* p) {
if (lock_count_ > 0)
return;
Lock lock(*this);
auto it = tracer_infos_.find(p);
if (it != tracer_infos_.end()) {
tracer_infos_.erase(it); // 会调用delete,死循环!!
}
}
void TracerNew::Dump() {
for (auto& tracer_info : tracer_infos_) {
std::cout << "0x" << tracer_info.first << ":\t" << tracer_info.second.File() << "\tIn Line:" << tracer_info.second.Line() << std::endl;
}
}
#endif
就是自定义new和delete