ZenLib
MemoryDebug.h
Go to the documentation of this file.
1 // ZenLib::MemoryDebug - To debug memory leaks
2 // Copyright (C) 2002-2011 MediaArea.net SARL, Info@MediaArea.net
3 //
4 // This software is provided 'as-is', without any express or implied
5 // warranty. In no event will the authors be held liable for any damages
6 // arising from the use of this software.
7 //
8 // Permission is granted to anyone to use this software for any purpose,
9 // including commercial applications, and to alter it and redistribute it
10 // freely, subject to the following restrictions:
11 //
12 // 1. The origin of this software must not be misrepresented; you must not
13 // claim that you wrote the original software. If you use this software
14 // in a product, an acknowledgment in the product documentation would be
15 // appreciated but is not required.
16 // 2. Altered source versions must be plainly marked as such, and must not be
17 // misrepresented as being the original software.
18 // 3. This notice may not be removed or altered from any source distribution.
19 //
20 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
22 // MemoryDebug
23 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
24 //
25 // Provide "new" and "delete" overloadings to be able to detect memory leaks
26 // Based on http://loulou.developpez.com/tutoriels/moteur3d/partie1/ 2.2.1
27 //
28 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29 
30 //---------------------------------------------------------------------------
31 #ifndef ZenMemoryDebugH
32 #define ZenMemoryDebugH
33 //---------------------------------------------------------------------------
34 
35 //---------------------------------------------------------------------------
36 #if defined(ZENLIB_DEBUG)
37 //---------------------------------------------------------------------------
38 #include "ZenLib/Conf.h"
39 #include <fstream>
40 #include <map>
41 #include <stack>
42 #include <string>
43 //---------------------------------------------------------------------------
44 
45 namespace ZenLib
46 {
47 
48 //***************************************************************************
49 // Class
50 //***************************************************************************
51 
52 class MemoryDebug
53 {
54 public :
55  ~MemoryDebug();
56  static MemoryDebug& Instance();
57 
58  void* Allocate(std::size_t Size, const char* File, int Line, bool Array);
59  void Free(void* Ptr, bool Array);
60  void NextDelete(const char*, int Line); //Sauvegarde les infos sur la désallocation courante
61 
62 private :
63  MemoryDebug();
64  void ReportLeaks();
65  struct TBlock
66  {
67  std::size_t Size; // Taille allouée
68  std::string File; // Fichier contenant l'allocation
69  int Line; // Ligne de l'allocation
70  bool Array; // Est-ce un objet ou un tableau ?
71  };
72  typedef std::map<void*, TBlock> TBlockMap;
73 
74  TBlockMap m_Blocks; // Blocs de mémoire alloués
75  std::stack<TBlock> m_DeleteStack; // Pile dont le sommet contient la ligne et le fichier de la prochaine désallocation
76 };
77 
78 } //NameSpace
79 
80 //***************************************************************************
81 // operator overloadings
82 //***************************************************************************
83 
84 inline void* operator new(std::size_t Size, const char* File, int Line)
85 {
86  return ZenLib::MemoryDebug::Instance().Allocate(Size, File, Line, false);
87 }
88 inline void* operator new[](std::size_t Size, const char* File, int Line)
89 {
90  return ZenLib::MemoryDebug::Instance().Allocate(Size, File, Line, true);
91 }
92 
93 inline void operator delete(void* Ptr)
94 {
95  ZenLib::MemoryDebug::Instance().Free(Ptr, false);
96 }
97 
98 inline void operator delete[](void* Ptr)
99 {
100  ZenLib::MemoryDebug::Instance().Free(Ptr, true);
101 }
102 
103 #if !defined(__BORLANDC__) // Borland does not support overloaded delete
104 inline void operator delete(void* Ptr, const char* File, int Line)
105 {
106  ZenLib::MemoryDebug::Instance().NextDelete(File, Line);
107  ZenLib::MemoryDebug::Instance().Free(Ptr, false);
108 }
109 
110 inline void operator delete[](void* Ptr, const char* File, int Line)
111 {
112  ZenLib::MemoryDebug::Instance().NextDelete(File, Line);
113  ZenLib::MemoryDebug::Instance().Free(Ptr, true);
114 }
115 #endif
116 
117 #if !defined(__MINGW32__) //TODO: Does not work on MinGW, don't know why
118 #ifndef new
119  #define new new(__FILE__, __LINE__)
120 #endif
121 #ifndef delete
122  #define delete ZenLib::MemoryDebug::Instance().NextDelete(__FILE__, __LINE__), delete
123 #endif
124 #endif // __MINGW32__
125 
126 #endif // defined(ZENLIB_DEBUG)
127 
128 #endif // ZenMemoryDebugH
129 
130