Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

245 lines
6.1 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. //
  4. // objcnt.h --- Support for counting object instances.
  5. //
  6. //
  7. #ifndef __OBJCNT_H__
  8. #define __OBJCNT_H__
  9. /*
  10. This class catches class instance leaks. If you new a class, but do
  11. not delete it, this class will find it.
  12. The nice thing about this class is that it is very simple to use.
  13. Simple Instructions
  14. -------------------
  15. Assume X is the name of the class you want to count objects:
  16. 1. Inherit your class X from SI_COUNT(X).
  17. 2. Add the following line to a .CPP file in global scope:
  18. AUTO_CLASS_COUNT_CHECK(X) ;
  19. For more information refer to the detailed directions below.
  20. Detailed Instructions
  21. ---------------------
  22. 1. Inherit from one of the *_COUNT macros passing the name of the class your are tracking.
  23. If your class does not inherit from another class use SI_COUNT (Single Inheritance Count):
  24. class CHmData SI_COUNT(CHmData) // No ':'.
  25. {
  26. ....
  27. };
  28. // Notice that you do not use the ':' between the class name and the SI_COUNT macros.
  29. If your class inherits from another class use MI_COUNT (Multiple Inheritances) instead of
  30. SI_COUNT:
  31. class CExMergedTitleNode : MI_COUNT(CExMergerTitleNode)
  32. public CTitleNode
  33. {
  34. ...
  35. } ;
  36. // Notice that you need the ':' when using MI_COUNT. However, DO NOT use the ending comma ','.
  37. If your class has to inherit from another class first, for example CHHWinType, use MI2_COUNT and
  38. place it last on the inheritance chain:
  39. class CHHWinType : public HH_WINTYPE
  40. MI2_COUNT(CHHWinType)
  41. {
  42. ...
  43. };
  44. // Notice that there isn't a comma before MI2_COUNT.
  45. 2. If you want to automatically, check the allocation/deallocation count at CRT shutdown,
  46. use the AUTO_CLASS_COUNT_CHECK macro. In a .CPP file outside the scope of a function,
  47. place the following line:
  48. AUTO_CLASS_COUNT_CHECK(CExNode);
  49. where CExNode is the name of the class you want to automatically count.
  50. This macro creates a class which will call the check routine when it goes out of scope.
  51. This will happen when the CRTs are unloaded.
  52. 3. If you want to check the class object count at a specific instance, use the CHECK_CLASS_COUNT macro.
  53. CHECK_CLASS_COUNT(CExNode) ;
  54. This creates a function call to the Check function.
  55. This was used in the CloseWindow function in secwin.cpp to find out what was and wasn't cleaned up
  56. after closing a window.
  57. 4. The best way to catch the messages is to place a break point on the line below with the DebugBreak call.
  58. A message box will normally be displayed showing the count. However, due to the threading issues
  59. sometimes the thread goes away before the Messsage box is visible.
  60. */
  61. ///////////////////////////////////////////////////////////////////////////////
  62. //
  63. // Global Helper function
  64. //
  65. ///////////////////////////////////////////////////////////////////////////////
  66. //
  67. // Forwards
  68. //
  69. template <typename X> class CAutoClassCountCheck;
  70. ///////////////////////////////////////////////////////////////////////////////
  71. //
  72. // CClassObjectCount
  73. //
  74. template <typename X>
  75. class CClassObjectCount
  76. {
  77. friend class CAutoClassCountCheck<X> ;
  78. public:
  79. // Constructor
  80. CClassObjectCount()
  81. {
  82. m_construct++ ;
  83. }
  84. // Destructor
  85. ~CClassObjectCount()
  86. {
  87. m_destruct++ ;
  88. }
  89. // Dump the statistics.
  90. static void Dump(const char* szName)
  91. {
  92. #if 0
  93. char buf[256] ;
  94. wsprintf(buf, "construct:%d\ndestruct:%d", m_construct, m_destruct) ;
  95. MessageBox(NULL, buf, szName, MB_OK | MB_TASKMODAL | MB_ICONEXCLAMATION);
  96. #else
  97. char buf2[1024];
  98. wsprintf( buf2, "*** Memory Leak: %s class, construct:%d, destruct:%d\r\n", szName, m_construct, m_destruct );
  99. OutputDebugString( buf2 );
  100. #endif
  101. }
  102. // Check to see if everything was deallocated.
  103. static void Check(const char* szName)
  104. {
  105. if (m_construct != m_destruct)
  106. {
  107. //--- PLACE BREAK POINT HERE ---
  108. //DebugBreak() ;
  109. Dump(szName) ;
  110. }
  111. }
  112. private:
  113. // Member variables.
  114. static int m_construct;
  115. static int m_destruct;
  116. };
  117. ///////////////////////////////////////////////////////////////////////////////
  118. //
  119. // statics
  120. //
  121. template <typename X>
  122. int CClassObjectCount<X>::m_construct = 0;
  123. template <typename X>
  124. int CClassObjectCount<X>::m_destruct = 0;
  125. ///////////////////////////////////////////////////////////////////////////////
  126. //
  127. // CAutoClassCountCheck
  128. //
  129. template <typename X>
  130. class CAutoClassCountCheck
  131. {
  132. public:
  133. CAutoClassCountCheck(const char* name)
  134. {
  135. m_name = name ;
  136. }
  137. virtual ~CAutoClassCountCheck()
  138. {
  139. CClassObjectCount<X>::Check(m_name);
  140. }
  141. public:
  142. const char* m_name ;
  143. };
  144. ///////////////////////////////////////////////////////////////////////////////
  145. //
  146. // Macros
  147. //
  148. #ifdef _DEBUG
  149. /////////////////// DEBUG MACROS ///////////////////
  150. // Don't use this macro directly
  151. #define COUNT(x) private CClassObjectCount<x>
  152. // Use with multiple inheritance. Always first.
  153. #define MI_COUNT(x) COUNT(x),
  154. // Use with single inheritance. Always first.
  155. #define SI_COUNT(x) : COUNT(x)
  156. // Use with multiple inheritance. Always last.
  157. #define MI2_COUNT(x) ,COUNT(x)
  158. // Create a class which calls check on exit.
  159. #define AUTO_CLASS_COUNT_CHECK(x) \
  160. CAutoClassCountCheck<x> _dumpclass_##x(#x)
  161. // Check the class count.
  162. #define CHECK_CLASS_COUNT(x) \
  163. CClassObjectCount<x>::Check(#x)
  164. // Dump the class count
  165. #define DUMP_CLASS_COUNT(x)\
  166. CClassObjectCount<x>::Dump(#x)
  167. #else
  168. /////////////////// RELEASE MACROS ///////////////////
  169. #define COUNT(x)
  170. #define MI_COUNT(x)
  171. #define SI_COUNT(x)
  172. #define MI2_COUNT(x)
  173. #define AUTO_CLASS_COUNT_CHECK(x)
  174. #define CHECK_CLASS_COUNT(x)
  175. #define DUMP_CLASS_COUNT(x)
  176. #endif
  177. #endif __OBJCNT_H__