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 <sstream> 00027 #include <memory> 00028 #include <map> 00029 #include <stack> 00030 #include <string> 00031 //--------------------------------------------------------------------------- 00032 00033 namespace ZenLib 00034 { 00035 00036 //*************************************************************************** 00037 // Class 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); //Sauvegarde les infos sur la désallocation courante 00049 00050 void ReportLeaks(); 00051 00052 private : 00053 MemoryDebug(); 00054 struct TBlock 00055 { 00056 std::size_t Size; // Taille allouée 00057 std::string File; // Fichier contenant l'allocation 00058 int Line; // Ligne de l'allocation 00059 bool Array; // Est-ce un objet ou un tableau ? 00060 }; 00061 typedef std::map<void*, TBlock> TBlockMap; 00062 00063 TBlockMap m_Blocks; // Blocs de mémoire alloués 00064 std::stack<TBlock> m_DeleteStack; // Pile dont le sommet contient la ligne et le fichier de la prochaine désallocation 00065 }; 00066 00067 } //NameSpace 00068 00069 //*************************************************************************** 00070 // operator overloadings 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