ZenLib
|
00001 /* Copyright (c) MediaArea.net SARL. All Rights Reserved. 00002 * 00003 * Use of this source code is governed by a zlib-style license that can 00004 * be found in the License.txt file in the root of the source tree. 00005 */ 00006 00007 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00008 // 00009 // MemoryDebug 00010 // 00011 // Provide "new" and "delete" overloadings to be able to detect memory leaks 00012 // Based on http://loulou.developpez.com/tutoriels/moteur3d/partie1/ 2.2.1 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 <map> 00027 #include <stack> 00028 #include <string> 00029 //--------------------------------------------------------------------------- 00030 00031 namespace ZenLib 00032 { 00033 00034 //*************************************************************************** 00035 // Class 00036 //*************************************************************************** 00037 00038 class MemoryDebug 00039 { 00040 public : 00041 ~MemoryDebug(); 00042 static MemoryDebug& Instance(); 00043 static bool g_IsShutdown; 00044 void* Allocate(std::size_t Size, const char* File, int Line, bool Array); 00045 void Free(void* Ptr, bool Array); 00046 void NextDelete(const char*, int Line); //Sauvegarde les infos sur la désallocation courante 00047 00048 void ReportLeaks(); 00049 00050 private : 00051 MemoryDebug(); 00052 struct TBlock 00053 { 00054 std::size_t Size; // Taille allouée 00055 std::string File; // Fichier contenant l'allocation 00056 int Line; // Ligne de l'allocation 00057 bool Array; // Est-ce un objet ou un tableau ? 00058 }; 00059 typedef std::map<void*, TBlock> TBlockMap; 00060 00061 TBlockMap m_Blocks; // Blocs de mémoire alloués 00062 std::stack<TBlock> m_DeleteStack; // Pile dont le sommet contient la ligne et le fichier de la prochaine désallocation 00063 }; 00064 00065 } //NameSpace 00066 00067 //*************************************************************************** 00068 // operator overloadings 00069 //*************************************************************************** 00070 00071 inline void* operator new(std::size_t Size, const char* File, int Line) 00072 { 00073 return ZenLib::MemoryDebug::Instance().Allocate(Size, File, Line, false); 00074 } 00075 inline void* operator new[](std::size_t Size, const char* File, int Line) 00076 { 00077 return ZenLib::MemoryDebug::Instance().Allocate(Size, File, Line, true); 00078 } 00079 00080 inline void operator delete(void* Ptr) 00081 { 00082 if (ZenLib::MemoryDebug::g_IsShutdown) 00083 free(Ptr); 00084 else 00085 ZenLib::MemoryDebug::Instance().Free(Ptr, false); 00086 } 00087 00088 inline void operator delete[](void* Ptr) 00089 { 00090 if (ZenLib::MemoryDebug::g_IsShutdown) 00091 free(Ptr); 00092 else 00093 ZenLib::MemoryDebug::Instance().Free(Ptr, true); 00094 } 00095 00096 #if !defined(__BORLANDC__) // Borland does not support overloaded delete 00097 inline void operator delete(void* Ptr, const char* File, int Line) 00098 { 00099 ZenLib::MemoryDebug::Instance().NextDelete(File, Line); 00100 ZenLib::MemoryDebug::Instance().Free(Ptr, false); 00101 } 00102 00103 inline void operator delete[](void* Ptr, const char* File, int Line) 00104 { 00105 ZenLib::MemoryDebug::Instance().NextDelete(File, Line); 00106 ZenLib::MemoryDebug::Instance().Free(Ptr, true); 00107 } 00108 #endif 00109 00110 #if !defined(__MINGW32__) //TODO: Does not work on MinGW, don't know why 00111 #ifndef new 00112 #define new new(__FILE__, __LINE__) 00113 #endif 00114 #ifndef delete 00115 #define delete ZenLib::MemoryDebug::Instance().NextDelete(__FILE__, __LINE__), delete 00116 #endif 00117 #endif // __MINGW32__ 00118 00119 #endif // defined(ZENLIB_DEBUG) 00120 00121 #endif // ZenMemoryDebugH