程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 內存洩露檢查之C++實現

內存洩露檢查之C++實現

編輯:C++入門知識

從事C++研發的筒子們,最揮之不去可能要算內存洩露帶來的痛苦吧,在C++中,雖說其實現底層代碼方面所凸顯出來的性能要遠高於其他類型語言,但是其由於缺乏天生的內存回收機制,從而也被業界予以诟病,那有沒有辦法能夠監測到程序中的內存洩露問題呢,其實是有很多的辦法,例如efence ,vagrind類型的工具等,但是這些工具最大的問題就是太重量級了,需要在自己的代碼中安插部分調試代碼,使用起來也是不很方便,基於此,本人通過學習前人的一些方法,稍微對new,delete進行了重載,基本上實現了檢查程序中的內存洩露問題,好了,下面來看代碼吧:

#include
#include
#include
#include
using namespace boost;

#define MEM_CHECK_TABLESIZE 1024*1024
#define MEM_HASH_FUNC(ptr) ((reinterpret_cast(ptr))%MEM_CHECK_TABLESIZE)
#define MEM_FILENAME_SIZE 1024

boost::mutex mut;
boost::mutex mem_mut;
struct allocMem_ptr_t
{
    allocMem_ptr_t()
    {
        bzero(fileName,sizeof(fileName));
        size = 0;
        line = 0;
        next = NULL;
    }
    char fileName[MEM_FILENAME_SIZE];
    int size;
    int line;
    allocMem_ptr_t* next;
};

struct allocMem_ptr_t* allocMem_list[MEM_CHECK_TABLESIZE];
int tableSize = 0;

struct memLeak_ptr_t
{
    memLeak_ptr_t()
    {
        bzero(fileName,sizeof(fileName));
        size = 0;
    }
    char fileName[MEM_FILENAME_SIZE];
    int size;
};
std::map memLeak_map;
void memCheck()
{
    size_t index = 0;
    mem_mut.lock();
    for(int i=0;ifileName,alloc->line);
            memLeak.size = alloc->size;
            memLeak_map.insert(std::make_pair(index,memLeak));
            alloc = alloc->next;
            index++;
        }
    }
    mem_mut.unlock();
    std::map leakCount;
    for(int i =0;i::iterator leakCount_iter;
    for(leakCount_iter iter = leakCount.begin();iter != leakCount.end();++iter)
    {
        printf("%s LEAK MEMORY SIZE:%d\n",iter->first.c_str(),iter->second);
    }
}
void* operator new(size_t size,const char* file,int line)
{
    size_t siz = size + sizeof(allocMem_ptr_t);
    allocMem_ptr_t* ptr = (allocMem_ptr_t*)::malloc(siz);
    if(NULL == ptr) abort();
    void* p = (char*)ptr + sizeof(allocMem_ptr_t);
    strncpy(ptr->fileName,file,MEM_FILENAME_SIZE-1);
    ptr->size = size;
    ptr->line = line;

    mem_mut.lock();
    size_t index = MEM_HASH_FUNC(p);
    ptr->next = allocMem_list[index];
    allocMem_list[index] = ptr;
    ++tableSize;
    mem_mut.unlock();
    return p;
}

void* operator new[](size_t size,const char* file,int line)
{
    return operator new(size,file,line);
}

void operator delete(void* ptr)
{
    if(NULL == ptr) return;
    allocMem_ptr_t* pre = NULL;
    size_t index = MEM_HASH_FUNC(ptr);
    mem_mut.lock();
    allocMem_ptr_t* pointer = allocMem_list[index];
    while(pointer)
    {
        if((char*)pointer + sizeof(allocMem_ptr_t) == ptr)
        {
            if(NULL == pre)
                allocMem_list[index] = pointer->next;
            else
                pre->next = pointer->next;
            --tableSize;
            break;
        }
        pre = pointer;
        pointer = pointer->next;
    }
    mem_mut.unlock();
    free(pointer);
}

void operator delete[](void* pointer)
{
    operator delete(pointer);
}

void operator delete(void* pointer,const char* file,int line)
{
    operator delete(pointer);
}
void operator delete[](void* pointer,const char* file,int line)
{
    operator delete(pointer);
}
#ifndef __MEM_CHECK__H
#define __MEM_CHECK__H
#include
#include
#define MEM_CHECK memCheck()
void memCheck();
void* operator new(size_t size,const char* file,int line);
void* operator new[](size_t size,const char* file,int line);

void operator delete(void* pointer,const char* file,int line);
void operator delete[](void* pointer,const char* file,int line);

#define  MEM_ALLOC new(__FILE__,__LINE__)
#define  MEM_DELETE delete
#endif

測試程序:

#include "MemCheck.h"


struct point
{
    point()
    {
        posX = 0;
        posY = 0;
    }
    int posX;
    int posY;
};

int main(int argc,char* argv[])
{
    int* pointer = MEM_ALLOC int();
    double* doub = MEM_ALLOC double();
    std::string* str = MEM_ALLOC std::string();
    point* po = MEM_ALLOC point();
    MEM_DELETE pointer;
    MEM_DELETE po;
    MEM_CHECK;
    return 0;
}

測試結果:

Test.cpp:18 LEAK MEMORY SIZE:8
Test.cpp:19 LEAK MEMORY SIZE:4

總結

本篇博文主要是通過封裝new、delete操作,實現了一個簡單版的檢查內存洩露工具,原理很簡單:通過一個簡單的hash表來存放相關的內存分配信息,這個hash表會隨著內存分配操作而動態的調整,這個實現思路其實還是有部分的問題,但總體上來將還是應用於實際的項目,好好地體會吧,有機會的話,我們可以使用redis來改寫下這個功能,好了,本篇博文到此結束。

如果需要,請注明轉載,多謝

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved