检测内存泄漏

一、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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值