DebugNew.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. #ifndef DEBUGNEW_H_
  2. #define DEBUGNEW_H_
  3. /**
  4. * Global overrides of the new and delete operators for memory tracking.
  5. * This file is only included when memory leak detection is explicitly
  6. * request via the pre-processor definition GP_USE_MEM_LEAK_DETECTION.
  7. */
  8. #ifdef GP_USE_MEM_LEAK_DETECTION
  9. #include <new>
  10. #include <exception>
  11. // Prints all heap and reference leaks to stderr.
  12. extern void printMemoryLeaks();
  13. // global new/delete operator overloads
  14. #ifdef _MSC_VER
  15. #pragma warning( disable : 4290 ) // C++ exception specification ignored.
  16. #endif
  17. void* operator new (std::size_t size, const char* file, int line);
  18. void* operator new[] (std::size_t size, const char* file, int line);
  19. void* operator new (std::size_t size) throw(std::bad_alloc);
  20. void* operator new[] (std::size_t size) throw(std::bad_alloc);
  21. void* operator new (std::size_t size, const std::nothrow_t&) throw();
  22. void* operator new[] (std::size_t size, const std::nothrow_t&) throw();
  23. void operator delete (void* p) throw();
  24. void operator delete[] (void* p) throw();
  25. void operator delete (void* p, const char* file, int line) throw();
  26. void operator delete[] (void* p, const char* file, int line) throw();
  27. #ifdef _MSC_VER
  28. #pragma warning( default : 4290 )
  29. #endif
  30. // Re-define new to use versions with file and line number
  31. #define DEBUG_NEW new (__FILE__, __LINE__)
  32. #define new DEBUG_NEW
  33. #endif
  34. // Since Bullet overrides new, we define custom functions to allocate Bullet objects that undef
  35. // 'new' before allocation and redefine it to our custom version afterwards (we support 0-2, 9 parameter constructors).
  36. template<typename T> T* bullet_new()
  37. {
  38. #ifdef GP_USE_MEM_LEAK_DETECTION
  39. #undef new
  40. T* t = new T();
  41. #define new DEBUG_NEW
  42. return t;
  43. #else
  44. return new T();
  45. #endif
  46. }
  47. template<typename T, typename T1> T* bullet_new(const T1& t1)
  48. {
  49. #ifdef GP_USE_MEM_LEAK_DETECTION
  50. #undef new
  51. T* t = new T(t1);
  52. #define new DEBUG_NEW
  53. return t;
  54. #else
  55. return new T(t1);
  56. #endif
  57. }
  58. template<typename T, typename T1, typename T2> T* bullet_new(const T1& t1, const T2& t2)
  59. {
  60. #ifdef GP_USE_MEM_LEAK_DETECTION
  61. #undef new
  62. T* t = new T(t1, t2);
  63. #define new DEBUG_NEW
  64. return t;
  65. #else
  66. return new T(t1, t2);
  67. #endif
  68. }
  69. template<typename T, typename T1, typename T2> T* bullet_new(T1& t1, const T2& t2)
  70. {
  71. #ifdef GP_USE_MEM_LEAK_DETECTION
  72. #undef new
  73. T* t = new T(t1, t2);
  74. #define new DEBUG_NEW
  75. return t;
  76. #else
  77. return new T(t1, t2);
  78. #endif
  79. }
  80. template<typename T, typename T1, typename T2, typename T3>
  81. T* bullet_new(const T1& t1, const T2& t2, const T3& t3)
  82. {
  83. #ifdef GP_USE_MEM_LEAK_DETECTION
  84. #undef new
  85. T* t = new T(t1, t2, t3);
  86. #define new DEBUG_NEW
  87. return t;
  88. #else
  89. return new T(t1, t2, t3);
  90. #endif
  91. }
  92. template<typename T, typename T1, typename T2, typename T3>
  93. T* bullet_new(T1& t1, const T2& t2, const T3& t3)
  94. {
  95. #ifdef GP_USE_MEM_LEAK_DETECTION
  96. #undef new
  97. T* t = new T(t1, t2, t3);
  98. #define new DEBUG_NEW
  99. return t;
  100. #else
  101. return new T(t1, t2, t3);
  102. #endif
  103. }
  104. template<typename T, typename T1, typename T2, typename T3, typename T4>
  105. T* bullet_new(const T1& t1, const T2& t2, const T3& t3, const T4& t4)
  106. {
  107. #ifdef GP_USE_MEM_LEAK_DETECTION
  108. #undef new
  109. T* t = new T(t1, t2, t3, t4);
  110. #define new DEBUG_NEW
  111. return t;
  112. #else
  113. return new T(t1, t2, t3, t4);
  114. #endif
  115. }
  116. template<typename T, typename T1, typename T2, typename T3, typename T4>
  117. T* bullet_new(T1& t1, const T2& t2, const T3& t3, const T4& t4)
  118. {
  119. #ifdef GP_USE_MEM_LEAK_DETECTION
  120. #undef new
  121. T* t = new T(t1, t2, t3, t4);
  122. #define new DEBUG_NEW
  123. return t;
  124. #else
  125. return new T(t1, t2, t3, t4);
  126. #endif
  127. }
  128. template<typename T, typename T1, typename T2, typename T3, typename T4>
  129. T* bullet_new(T1& t1, T2& t2, const T3& t3, const T4& t4)
  130. {
  131. #ifdef GP_USE_MEM_LEAK_DETECTION
  132. #undef new
  133. T* t = new T(t1, t2, t3, t4);
  134. #define new DEBUG_NEW
  135. return t;
  136. #else
  137. return new T(t1, t2, t3, t4);
  138. #endif
  139. }
  140. template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
  141. T* bullet_new(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
  142. {
  143. #ifdef GP_USE_MEM_LEAK_DETECTION
  144. #undef new
  145. T* t = new T(t1, t2, t3, t4, t5);
  146. #define new DEBUG_NEW
  147. return t;
  148. #else
  149. return new T(t1, t2, t3, t4, t5);
  150. #endif
  151. }
  152. template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5>
  153. T* bullet_new(T1& t1, T2& t2, const T3& t3, const T4& t4, const T5& t5)
  154. {
  155. #ifdef GP_USE_MEM_LEAK_DETECTION
  156. #undef new
  157. T* t = new T(t1, t2, t3, t4, t5);
  158. #define new DEBUG_NEW
  159. return t;
  160. #else
  161. return new T(t1, t2, t3, t4, t5);
  162. #endif
  163. }
  164. template<typename T, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
  165. T* bullet_new(const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9)
  166. {
  167. #ifdef GP_USE_MEM_LEAK_DETECTION
  168. #undef new
  169. T* t = new T(t1, t2, t3, t4, t5, t6, t7, t8, t9);
  170. #define new DEBUG_NEW
  171. return t;
  172. #else
  173. return new T(t1, t2, t3, t4, t5, t6, t7, t8, t9);
  174. #endif
  175. }
  176. #if defined(WIN32)
  177. /**
  178. * Sets whether stack traces are tracked on memory allocations or not.
  179. *
  180. * @param trackStackTrace Whether to track the stack trace on memory allocations.
  181. */
  182. void setTrackStackTrace(bool trackStackTrace);
  183. /**
  184. * Toggles stack trace tracking on memory allocations.
  185. */
  186. void toggleTrackStackTrace();
  187. #endif
  188. #endif