54 跟踪内存泄漏

自己实现malloc,在里面进行跟踪
valgrind、dmalloc、efence (linux)
visual leak detector(windows)

operator new
operator delete

new operator <=>operator new + 构造函数

头文件包含次序
C库、C++库、其他库.h 、项目中.h

//Tracer.h
#ifndef _TRACER_H_
#define _TRACER_H_

#include <map>

#ifndef NDEBUG
void* operator new(size_t size, const char* file, long line);
//void* operator new(size_t size);
void* operator new[](size_t size, const char* file, long line);
void* operator new[](size_t size);
void operator delete(void* p, const char*, long);
void operator delete(void* p);//重载
void operator delete[](void* p, const char*, long);//重载
void operator delete[](void* p);//重载

class Tracer
{
private:
    class Entry
    {
    public:
        Entry(const char* file = 0, long line = 0)
            :file_(file), line_(line){}
        const char* File() const { return file_; }
        long Line() const { return line_; }
    private:
        const char* file_;
        long line_;
    };
public:
    Tracer();
    ~Tracer();
    static bool Ready;

    void Add(void* p, const char* file, long line);
    void Remove(void* p);
    void Dump(); 
private:
    std::map<void*, Entry>mapEntry_;
};

extern Tracer NewTrace;

#endif//NDEBUG
#endif

//Tracer.cpp
#include <iostream>
#include "Tracer.h"

#ifndef NDEBUG
bool Tracer::Ready = false;

Tracer::Tracer()
{
    Ready = true;
}


Tracer::~Tracer()
{
    Ready = false;
    Dump();
}


void Tracer::Add(void* p, const char* file, long line)
{
    mapEntry_[p] = Entry(file,line);
}
void Tracer::Remove(void* p)
{
    std::map<void*, Entry>::const_iterator it;
    it = mapEntry_.find(p);
    if (it != mapEntry_.end())
    {
        mapEntry_.erase(it);
    }
}
void Tracer::Dump()
{
    if (mapEntry_.size()>0)
    {
        std::cout << "*** Memory leak(s):" << std::endl;
        std::map<void*, Entry>::const_iterator it;
        for (it = mapEntry_.begin(); it != mapEntry_.end(); ++it)
        {
            const char* file = it->second.File();
            long line = it->second.Line();
            int addr = reinterpret_cast<int>(it->first);
            std::cout << "0x" << std::hex << addr << ": "
                << file << ", line " << std::dec << line << std::endl;
        }
        std::cout << std::endl;

    }
}

Tracer NewTrace;

void* operator new(size_t size, const char* file, long line)
{
    void* p = malloc(size);
    if (Tracer::Ready)
    {
        NewTrace.Add(p, file, line);
    }
    return p;
}
void* operator new[](size_t size, const char* file, long line)
{
    void* p = malloc(size);
    if (Tracer::Ready)
    {
        NewTrace.Add(p, file, line);
    }
    return p;
}
void* operator new[](size_t size)
{
    void* p = malloc(size);
    if (Tracer::Ready)
    {
        NewTrace.Add(p, "?", 0);
    }
    return p;
}
//void* operator new(size_t size)
//{
//  void* p = malloc(size);
//  if (Tracer::Ready)
//  {
//      NewTrace.Add(p, "?", 0);
//  }
//  return p;
//}
void operator delete(void*p, const char*, long)
{
    if (Tracer::Ready)
    {
        NewTrace.Remove(p);
    }
    free(p);
}

void operator delete(void* p)
{
    if (Tracer::Ready)
    {
        NewTrace.Remove(p);
    }
    free(p);
}
void operator delete[](void*p, const char*, long)
{
    if (Tracer::Ready)
    {
        NewTrace.Remove(p);
    }
    free(p);
}
void operator delete[](void*p)
{
    if (Tracer::Ready)
    {
        NewTrace.Remove(p);
    }
    free(p);
}

#endif

//DebugNew.h
#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_

#ifndef NDEBUG
#include "Tracer.h"

#define new new(__FILE__, __LINE__)

#endif
#endif

//main.cpp
#include<iostream>
using namespace std;

#include"DebugNew.h"



int main(void)
{
    int* p = new int;//堆栈开辟四个字节的空间
    //delete p;

    int* p2 = new int[5];
    //delete[] p2;

    return 0;
}

解决程序运行终止的问题

//Tracer.h
#ifndef _TRACER_H_
#define _TRACER_H_

#include <map>

#ifndef NDEBUG
void* operator new(size_t size, const char* file, long line);
void* operator new(size_t size);
void* operator new[](size_t size, const char* file, long line);
void* operator new[](size_t size);
void operator delete(void* p, const char*, long);
void operator delete(void* p);//重载
void operator delete[](void* p, const char*, long);//重载
void operator delete[](void* p);//重载

class Tracer
{
private:
    class Entry
    {
    public:
        Entry(const char* file = 0, long line = 0)
            :file_(file), line_(line){}
        const char* File() const { return file_; }
        long Line() const { return line_; }
    private:
        const char* file_;
        long line_;
    };

    class Lock
    {
    public:
        Lock(Tracer& tracer) :tracer_(tracer)
        {
            tracer_.lock();
        }
        ~Lock()
        {
            tracer_.unlock();
        }
    private:
        Tracer& tracer_;

    };
    friend class Lock;
public:
    Tracer();
    ~Tracer();
    static bool Ready;

    void Add(void* p, const char* file, long line);
    void Remove(void* p);
    void Dump(); 
private:
    std::map<void*, Entry>mapEntry_;
    int lockCount_;
    void lock(){ ++lockCount_; }
    void unlock(){ --lockCount_; }
};

extern Tracer NewTrace;

#endif//NDEBUG
#endif

//Tracer.cpp
#include <iostream>
#include "Tracer.h"

#ifndef NDEBUG
bool Tracer::Ready = false;

Tracer::Tracer() :lockCount_(0)
{
    Ready = true;
}


Tracer::~Tracer()
{
    Ready = false;
    Dump();
}


void Tracer::Add(void* p, const char* file, long line)
{
    if (lockCount_ > 0)
        return;
    Tracer::Lock lock(*this);
    mapEntry_[p] = Entry(file,line);

}
void Tracer::Remove(void* p)
{
    if (lockCount_ > 0)
        return;

    Tracer::Lock lock(*this);
    std::map<void*, Entry>::const_iterator it;
    it = mapEntry_.find(p);
    if (it != mapEntry_.end())
    {
        mapEntry_.erase(it);
    }

}
void Tracer::Dump()
{
    if (mapEntry_.size()>0)
    {
        std::cout << "*** Memory leak(s):" << std::endl;
        std::map<void*, Entry>::const_iterator it;
        for (it = mapEntry_.begin(); it != mapEntry_.end(); ++it)
        {
            const char* file = it->second.File();
            long line = it->second.Line();
            int addr = reinterpret_cast<int>(it->first);
            std::cout << "0x" << std::hex << addr << ": "
                << file << ", line " << std::dec << line << std::endl;
        }
        std::cout << std::endl;

    }
}

Tracer NewTrace;

void* operator new(size_t size, const char* file, long line)
{
    void* p = malloc(size);
    if (Tracer::Ready)
    {
        NewTrace.Add(p, file, line);
    }
    return p;
}
void* operator new[](size_t size, const char* file, long line)
{
    void* p = malloc(size);
    if (Tracer::Ready)
    {
        NewTrace.Add(p, file, line);
    }
    return p;
}
void* operator new[](size_t size)
{
    void* p = malloc(size);
    if (Tracer::Ready)
    {
        NewTrace.Add(p, "?", 0);
    }
    return p;
}
void* operator new(size_t size)
{
    void* p = malloc(size);
    if (Tracer::Ready)
    {
        NewTrace.Add(p, "?", 0);
    }
    return p;
}
void operator delete(void*p, const char*, long)
{
    if (Tracer::Ready)
    {
        NewTrace.Remove(p);
    }
    free(p);
}

void operator delete(void* p)
{
    if (Tracer::Ready)
    {
        NewTrace.Remove(p);
    }
    free(p);
}
void operator delete[](void*p, const char*, long)
{
    if (Tracer::Ready)
    {
        NewTrace.Remove(p);
    }
    free(p);
}
void operator delete[](void*p)
{
    if (Tracer::Ready)
    {
        NewTrace.Remove(p);
    }
    free(p);
}

#endif

//DebugNew.h
#ifndef _DEBUG_NEW_H_
#define _DEBUG_NEW_H_

#ifndef NDEBUG
#include "Tracer.h"

#define new new(__FILE__, __LINE__)

#endif
#endif

//main.cpp
#include<iostream>
using namespace std;

#include"DebugNew.h"



int main(void)
{
    int* p = new int;//堆栈开辟四个字节的空间
    //delete p;

    int* p2 = new int[5];
    //delete[] p2;

    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值