ZenLib
|
00001 // ZenLib::MemoryDebug - To debug memory leaks 00002 // Copyright (C) 2002-2011 MediaArea.net SARL, Info@MediaArea.net 00003 // 00004 // This software is provided 'as-is', without any express or implied 00005 // warranty. In no event will the authors be held liable for any damages 00006 // arising from the use of this software. 00007 // 00008 // Permission is granted to anyone to use this software for any purpose, 00009 // including commercial applications, and to alter it and redistribute it 00010 // freely, subject to the following restrictions: 00011 // 00012 // 1. The origin of this software must not be misrepresented; you must not 00013 // claim that you wrote the original software. If you use this software 00014 // in a product, an acknowledgment in the product documentation would be 00015 // appreciated but is not required. 00016 // 2. Altered source versions must be plainly marked as such, and must not be 00017 // misrepresented as being the original software. 00018 // 3. This notice may not be removed or altered from any source distribution. 00019 // 00020 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00021 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00022 // MemoryDebug 00023 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00024 // 00025 // Provide "new" and "delete" overloadings to be able to detect memory leaks 00026 // Based on http://loulou.developpez.com/tutoriels/moteur3d/partie1/ 2.2.1 00027 // 00028 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 00029 00030 //--------------------------------------------------------------------------- 00031 #ifndef ZenMemoryDebugH 00032 #define ZenMemoryDebugH 00033 //--------------------------------------------------------------------------- 00034 00035 //--------------------------------------------------------------------------- 00036 #if defined(ZENLIB_DEBUG) 00037 //--------------------------------------------------------------------------- 00038 #include "ZenLib/Conf.h" 00039 #include <fstream> 00040 #include <map> 00041 #include <stack> 00042 #include <string> 00043 //--------------------------------------------------------------------------- 00044 00045 namespace ZenLib 00046 { 00047 00048 //*************************************************************************** 00049 // Class 00050 //*************************************************************************** 00051 00052 class MemoryDebug 00053 { 00054 public : 00055 ~MemoryDebug(); 00056 static MemoryDebug& Instance(); 00057 00058 void* Allocate(std::size_t Size, const char* File, int Line, bool Array); 00059 void Free(void* Ptr, bool Array); 00060 void NextDelete(const char*, int Line); //Sauvegarde les infos sur la désallocation courante 00061 00062 private : 00063 MemoryDebug(); 00064 void ReportLeaks(); 00065 struct TBlock 00066 { 00067 std::size_t Size; // Taille allouée 00068 std::string File; // Fichier contenant l'allocation 00069 int Line; // Ligne de l'allocation 00070 bool Array; // Est-ce un objet ou un tableau ? 00071 }; 00072 typedef std::map<void*, TBlock> TBlockMap; 00073 00074 TBlockMap m_Blocks; // Blocs de mémoire alloués 00075 std::stack<TBlock> m_DeleteStack; // Pile dont le sommet contient la ligne et le fichier de la prochaine désallocation 00076 }; 00077 00078 } //NameSpace 00079 00080 //*************************************************************************** 00081 // operator overloadings 00082 //*************************************************************************** 00083 00084 inline void* operator new(std::size_t Size, const char* File, int Line) 00085 { 00086 return ZenLib::MemoryDebug::Instance().Allocate(Size, File, Line, false); 00087 } 00088 inline void* operator new[](std::size_t Size, const char* File, int Line) 00089 { 00090 return ZenLib::MemoryDebug::Instance().Allocate(Size, File, Line, true); 00091 } 00092 00093 inline void operator delete(void* Ptr) 00094 { 00095 ZenLib::MemoryDebug::Instance().Free(Ptr, false); 00096 } 00097 00098 inline void operator delete[](void* Ptr) 00099 { 00100 ZenLib::MemoryDebug::Instance().Free(Ptr, true); 00101 } 00102 00103 #if !defined(__BORLANDC__) // Borland does not support overloaded delete 00104 inline void operator delete(void* Ptr, const char* File, int Line) 00105 { 00106 ZenLib::MemoryDebug::Instance().NextDelete(File, Line); 00107 ZenLib::MemoryDebug::Instance().Free(Ptr, false); 00108 } 00109 00110 inline void operator delete[](void* Ptr, const char* File, int Line) 00111 { 00112 ZenLib::MemoryDebug::Instance().NextDelete(File, Line); 00113 ZenLib::MemoryDebug::Instance().Free(Ptr, true); 00114 } 00115 #endif 00116 00117 #if !defined(__MINGW32__) //TODO: Does not work on MinGW, don't know why 00118 #ifndef new 00119 #define new new(__FILE__, __LINE__) 00120 #endif 00121 #ifndef delete 00122 #define delete ZenLib::MemoryDebug::Instance().NextDelete(__FILE__, __LINE__), delete 00123 #endif 00124 #endif // __MINGW32__ 00125 00126 #endif // defined(ZENLIB_DEBUG) 00127 00128 #endif // ZenMemoryDebugH 00129 00130