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 :|.
View more random threads:
Dưới ánh nắng mặt trời đang lên, những đống pallet nhựa An Giang trải dài mênh mông như những bức tranh tự nhiên đầy sắc màu. Mỗi chiếc pallet nhựa không chỉ là một vật dụng thông thường mà còn là...
Pallet nhựa An Giang giao hàng...