Cách chống memleak thì nói nhiều rồi, giờ tới cách "phát hiện và giải quyết hậu quả" của memleak :|.

Bản chất của memleak là cái gì?, memleak là new mà không delete, là alloc mà không free.

Từ đó muốn phát hiện leak thì ta phải ghi nhật ký xem những thằng nào đã new và đến khi hết chương trình nó đã delete chưa, nếu ku nào chưa tức là leak.

Cái thằng ghi nhật ký đó gọi là memory tracker.

MemoryTracker.h

Mã:
#ifndef _MEMORY_TRACKER_H_#define _MEMORY_TRACKER_H_ #include <map>#include <string>#include <sstream>#include <fstream>#include <iostream>#include <conio.h> class MemoryTracker{public:    struct Allocation    {        // Size        unsigned int size;        // File        std::string   file;        // Line        unsigned int line;        // Function        std::string  func;    }; private:    // Allocation map    typedef std::map<void*, Allocation> AllocationMap;    AllocationMap mAllocationMap;     // Total memory allocated    unsigned int  mTotalMemoryAllocated; private:    MemoryTracker()        : mTotalMemoryAllocated(0)    {    } public:    ~MemoryTracker()    {        std::ostringstream logStringStream;         // Build log string        if(mTotalMemoryAllocated == 0)        {            logStringStream << "No memory leaks detected";        }        else        {            logStringStream << "The following memory leaks were detected:

";             for (AllocationMap::const_iterator itr = mAllocationMap.begin(); itr != mAllocationMap.end(); ++itr)            {                logStringStream                 << itr->second.file  << "(" << itr->second.line << ", " << itr->second.func << "): "                 << itr->second.size  << " bytes
";            }             logStringStream << "
"            << mAllocationMap.size() << " leaks detected, "             << mTotalMemoryAllocated << " bytes total";        }         // Write log string to file        std::ofstream file;        file.open("Memory Leaks.log", std::ofstream::out | std::ofstream::trunc);        if(file.is_open())        {            file << logStringStream.str();            file.close();        }         // To standard output        std::cout << logStringStream.str();        _getch();    }     void AddAllocation    (        void* pointer,         unsigned int size,        const std::string& file,         unsigned int line,         const std::string& func    )    {        Allocation newAllocation;        newAllocation.size = size;        newAllocation.file = file;        newAllocation.line = line;        newAllocation.func = func;        mAllocationMap.insert(AllocationMap::value_type(pointer, newAllocation));         mTotalMemoryAllocated += newAllocation.size;    }     void RemoveAllocation(void* pointer)    {        if(!pointer)            return;         AllocationMap::iterator itr = mAllocationMap.find(pointer);        if(itr != mAllocationMap.end())        {            mTotalMemoryAllocated -= itr->second.size;            mAllocationMap.erase(itr);        }    } public:    static MemoryTracker& GetSingleton()    {        static MemoryTracker instance;        return instance;    }}; #define MEMORY_TRACKING #ifdef  MEMORY_TRACKING#   define MEM_TRACK_ADD(ptr, size) MemoryTracker::GetSingleton().AddAllocation(ptr, size, __FILE__, __LINE__, __FUNCTION__)#   define MEM_TRACK_REMOVE(ptr)    MemoryTracker::GetSingleton().RemoveAllocation(ptr)#else#   define MEM_TRACK_ADD(ptr, size) { }#   define MEM_TRACK_REMOVE(ptr)    { }#endif #endif // !_MEMORY_TRACKER_H_
Chú ý là khi release nên bỏ cái #define MEMORY_TRACKING đi kẻo mà user nó đập vào mặt cho lại bảo không báo trước [IMG]images/smilies/17.gif[/IMG] [IMG]images/smilies/11.gif[/IMG] .

Bây giờ thử nghiệm.

Mã:
#include "MemoryTracker.h" int main(){    // Alloc    int* a = new int[20];    MEM_TRACK_ADD(a, 20 * sizeof(int));     // Free    MEM_TRACK_REMOVE(a);    delete[] a;    return 0;}
Kết quả:

No memory leaks detected.
Giờ comment cái đoạn free vào cho nó leak.

Mã:
#include "MemoryTracker.h" int main(){    // Alloc    int* a = new int[20];    MEM_TRACK_ADD(a, 20 * sizeof(int));     // Free    /*MEM_TRACK_REMOVE(a);    delete[] a;*/    return 0;}
Kết quả là có chuyện vui vẻ xảy ra:

The following memory leaks were detected:

d:\memorytracker\memorytracker\main.cpp(7, main): 80 bytes

1 leaks detected, 80 bytes total
Tức là leak dòng thứ 7, function main(), 80 bytes :|.