00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef ZenMemoryDebugH
00018 #define ZenMemoryDebugH
00019
00020
00021
00022 #if defined(ZENLIB_DEBUG)
00023
00024 #include "ZenLib/Conf.h"
00025 #include <fstream>
00026 #include <sstream>
00027 #include <memory>
00028 #include <map>
00029 #include <stack>
00030 #include <string>
00031
00032
00033 namespace ZenLib
00034 {
00035
00036
00037
00038
00039
00040 class MemoryDebug
00041 {
00042 public :
00043 ~MemoryDebug();
00044 static MemoryDebug& Instance();
00045 static bool g_IsShutdown;
00046 void* Allocate(std::size_t Size, const char* File, int Line, bool Array);
00047 void Free(void* Ptr, bool Array);
00048 void NextDelete(const char*, int Line);
00049
00050 void ReportLeaks();
00051
00052 private :
00053 MemoryDebug();
00054 struct TBlock
00055 {
00056 std::size_t Size;
00057 std::string File;
00058 int Line;
00059 bool Array;
00060 };
00061 typedef std::map<void*, TBlock> TBlockMap;
00062
00063 TBlockMap m_Blocks;
00064 std::stack<TBlock> m_DeleteStack;
00065 };
00066
00067 }
00068
00069
00070
00071
00072
00073 inline void* operator new(std::size_t Size, const char* File, int Line)
00074 {
00075 return ZenLib::MemoryDebug::Instance().Allocate(Size, File, Line, false);
00076 }
00077 inline void* operator new[](std::size_t Size, const char* File, int Line)
00078 {
00079 return ZenLib::MemoryDebug::Instance().Allocate(Size, File, Line, true);
00080 }
00081
00082 inline void operator delete(void* Ptr)
00083 {
00084 if (ZenLib::MemoryDebug::g_IsShutdown)
00085 free(Ptr);
00086 else
00087 ZenLib::MemoryDebug::Instance().Free(Ptr, false);
00088 }
00089
00090 inline void operator delete[](void* Ptr)
00091 {
00092 if (ZenLib::MemoryDebug::g_IsShutdown)
00093 free(Ptr);
00094 else
00095 ZenLib::MemoryDebug::Instance().Free(Ptr, true);
00096 }
00097
00098 #if !defined(__BORLANDC__) // Borland does not support overloaded delete
00099 inline void operator delete(void* Ptr, const char* File, int Line)
00100 {
00101 ZenLib::MemoryDebug::Instance().NextDelete(File, Line);
00102 ZenLib::MemoryDebug::Instance().Free(Ptr, false);
00103 }
00104
00105 inline void operator delete[](void* Ptr, const char* File, int Line)
00106 {
00107 ZenLib::MemoryDebug::Instance().NextDelete(File, Line);
00108 ZenLib::MemoryDebug::Instance().Free(Ptr, true);
00109 }
00110 #endif
00111
00112 #if !defined(__MINGW32__) //TODO: Does not work on MinGW, don't know why
00113 #ifndef new
00114 #define new new(__FILE__, __LINE__)
00115 #endif
00116 #ifndef delete
00117 #define delete ZenLib::MemoryDebug::Instance().NextDelete(__FILE__, __LINE__), delete
00118 #endif
00119 #endif // __MINGW32__
00120
00121 #endif // defined(ZENLIB_DEBUG)
00122
00123 #endif // ZenMemoryDebugH