home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / MS_VC.50 / VC / MFC / SRC / AFXMEM.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-10-30  |  8.3 KB  |  321 lines

  1. // This is a part of the Microsoft Foundation Classes C++ library.
  2. // Copyright (C) 1992-1997 Microsoft Corporation
  3. // All rights reserved.
  4. //
  5. // This source code is only intended as a supplement to the
  6. // Microsoft Foundation Classes Reference and related
  7. // electronic documentation provided with the library.
  8. // See these sources for detailed information regarding the
  9. // Microsoft Foundation Classes product.
  10.  
  11. #include "stdafx.h"
  12.  
  13. #ifdef AFX_CORE1_SEG
  14. #pragma code_seg(AFX_CORE1_SEG)
  15. #endif
  16.  
  17. #ifdef _DEBUG
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21.  
  22. /////////////////////////////////////////////////////////////////////////////
  23. // Debug memory globals and implementation helpers
  24.  
  25. #ifdef _DEBUG       // most of this file is for debugging
  26.  
  27. /////////////////////////////////////////////////////////////////////////////
  28. // test allocation routines
  29.  
  30. void* PASCAL CObject::operator new(size_t nSize)
  31. {
  32. #ifdef _AFX_NO_DEBUG_CRT
  33.     return ::operator new(nSize);
  34. #else
  35.     return ::operator new(nSize, _CLIENT_BLOCK, NULL, 0);
  36. #endif // _AFX_NO_DEBUG_CRT
  37. }
  38.  
  39. void PASCAL CObject::operator delete(void* p)
  40. {
  41. #ifdef _AFX_NO_DEBUG_CRT
  42.     free(p);
  43. #else
  44.     _free_dbg(p, _CLIENT_BLOCK);
  45. #endif
  46. }
  47.  
  48. #ifndef _AFX_NO_DEBUG_CRT
  49.  
  50. void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
  51. {
  52.     return ::operator new(nSize, _NORMAL_BLOCK, lpszFileName, nLine);
  53. }
  54.  
  55. void* PASCAL
  56. CObject::operator new(size_t nSize, LPCSTR lpszFileName, int nLine)
  57. {
  58.     return ::operator new(nSize, _CLIENT_BLOCK, lpszFileName, nLine);
  59. }
  60.  
  61. void* AFXAPI AfxAllocMemoryDebug(size_t nSize, BOOL bIsObject,  LPCSTR lpszFileName, int nLine)
  62. {
  63.     return _malloc_dbg(nSize, bIsObject ? _CLIENT_BLOCK : _NORMAL_BLOCK,
  64.         lpszFileName, nLine);
  65. }
  66.  
  67. void AFXAPI AfxFreeMemoryDebug(void* pbData, BOOL bIsObject)
  68. {
  69.     _free_dbg(pbData, bIsObject ? _CLIENT_BLOCK : _NORMAL_BLOCK);
  70. }
  71.  
  72. /////////////////////////////////////////////////////////////////////////////
  73. // allocation failure hook, tracking turn on
  74.  
  75. BOOL AFXAPI _AfxDefaultAllocHook(size_t, BOOL, LONG)
  76.     { return TRUE; }
  77.  
  78. static AFX_ALLOC_HOOK pfnAllocHook = _AfxDefaultAllocHook;
  79.  
  80. static _CRT_ALLOC_HOOK pfnCrtAllocHook = NULL;
  81. int __cdecl _AfxAllocHookProxy(int nAllocType, void * pvData, size_t nSize,
  82.     int nBlockUse, long lRequest, const char * szFilename, int nLine)
  83. {
  84.     if (nAllocType != _HOOK_ALLOC)
  85.         return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
  86.             nBlockUse, lRequest, szFilename, nLine);
  87.     if ((pfnAllocHook)(nSize, _BLOCK_TYPE(nBlockUse) == _CLIENT_BLOCK, lRequest))
  88.         return (pfnCrtAllocHook)(nAllocType, pvData, nSize,
  89.             nBlockUse, lRequest, szFilename, nLine);
  90.     return FALSE;
  91. }
  92.  
  93. AFX_ALLOC_HOOK AFXAPI AfxSetAllocHook(AFX_ALLOC_HOOK pfnNewHook)
  94. {
  95.     if (pfnCrtAllocHook == NULL)
  96.         pfnCrtAllocHook = _CrtSetAllocHook(_AfxAllocHookProxy);
  97.  
  98.     AFX_ALLOC_HOOK pfnOldHook = pfnAllocHook;
  99.     pfnAllocHook = pfnNewHook;
  100.     return pfnOldHook;
  101. }
  102.  
  103. // This can be set to TRUE to override all AfxEnableMemoryTracking calls,
  104. // allowing all allocations, even MFC internal allocations to be tracked.
  105. BOOL _afxMemoryLeakOverride = FALSE;
  106.  
  107. BOOL AFXAPI AfxEnableMemoryTracking(BOOL bTrack)
  108. {
  109.     if (_afxMemoryLeakOverride)
  110.         return TRUE;
  111.  
  112.     int nOldState = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  113.     if (bTrack)
  114.         _CrtSetDbgFlag(nOldState | _CRTDBG_ALLOC_MEM_DF);
  115.     else
  116.         _CrtSetDbgFlag(nOldState & ~_CRTDBG_ALLOC_MEM_DF);
  117.     return nOldState & _CRTDBG_ALLOC_MEM_DF;
  118. }
  119.  
  120. /////////////////////////////////////////////////////////////////////////////
  121. // stop on a specific memory request
  122.  
  123. // Obsolete API
  124. void AFXAPI AfxSetAllocStop(LONG lRequestNumber)
  125. {
  126.     _CrtSetBreakAlloc(lRequestNumber);
  127. }
  128.  
  129. BOOL AFXAPI AfxCheckMemory()
  130.   // check all of memory (look for memory tromps)
  131. {
  132.     return _CrtCheckMemory();
  133. }
  134.  
  135. // -- true if block of exact size, allocated on the heap
  136. // -- set *plRequestNumber to request number (or 0)
  137. BOOL AFXAPI AfxIsMemoryBlock(const void* pData, UINT nBytes,
  138.         LONG* plRequestNumber)
  139. {
  140.     return _CrtIsMemoryBlock(pData, nBytes, plRequestNumber, NULL, NULL);
  141. }
  142.  
  143. /////////////////////////////////////////////////////////////////////////////
  144. // CMemoryState
  145.  
  146. CMemoryState::CMemoryState()
  147. {
  148.     memset(this, 0, sizeof(*this));
  149. }
  150.  
  151. void CMemoryState::UpdateData()
  152. {
  153.     for(int i = 0; i < nBlockUseMax; i++)
  154.     {
  155.         m_lCounts[i] = m_memState.lCounts[i];
  156.         m_lSizes[i] = m_memState.lSizes[i];
  157.     }
  158.     m_lHighWaterCount = m_memState.lHighWaterCount;
  159.     m_lTotalCount = m_memState.lTotalCount;
  160. }
  161.  
  162. // fills 'this' with the difference, returns TRUE if significant
  163. BOOL CMemoryState::Difference(const CMemoryState& oldState,
  164.         const CMemoryState& newState)
  165. {
  166.     int nResult = _CrtMemDifference(&m_memState, &oldState.m_memState, &newState.m_memState);
  167.     UpdateData();
  168.     return nResult != 0;
  169. }
  170.  
  171. void CMemoryState::DumpStatistics() const
  172. {
  173.     _CrtMemDumpStatistics(&m_memState);
  174. }
  175.  
  176. // -- fill with current memory state
  177. void CMemoryState::Checkpoint()
  178. {
  179.     _CrtMemCheckpoint(&m_memState);
  180.     UpdateData();
  181. }
  182.  
  183. // Dump objects created after this memory state was checkpointed
  184. // Will dump all objects if this memory state wasn't checkpointed
  185. // Dump all objects, report about non-objects also
  186. // List request number in {}
  187. void CMemoryState::DumpAllObjectsSince() const
  188. {
  189.     _CrtMemDumpAllObjectsSince(&m_memState);
  190. }
  191.  
  192. /////////////////////////////////////////////////////////////////////////////
  193. // Enumerate all objects allocated in the diagnostic memory heap
  194.  
  195. struct _AFX_ENUM_CONTEXT
  196. {
  197.     void (*m_pfn)(CObject*,void*);
  198.     void* m_pContext;
  199. };
  200.  
  201. static void _AfxDoForAllObjectsProxy(void* pObject, void* pContext)
  202. {
  203.     _AFX_ENUM_CONTEXT* p = (_AFX_ENUM_CONTEXT*)pContext;
  204.     (*p->m_pfn)((CObject*)pObject, p->m_pContext);
  205. }
  206.  
  207. void AFXAPI
  208. AfxDoForAllObjects(void (AFX_CDECL *pfn)(CObject*, void*), void* pContext)
  209. {
  210.     _AFX_ENUM_CONTEXT context;
  211.     context.m_pfn = pfn;
  212.     context.m_pContext = pContext;
  213.     _CrtDoForAllClientObjects(_AfxDoForAllObjectsProxy, &context);
  214. }
  215.  
  216. /////////////////////////////////////////////////////////////////////////////
  217. // Automatic debug memory diagnostics
  218.  
  219. BOOL AFXAPI AfxDumpMemoryLeaks()
  220. {
  221.     return _CrtDumpMemoryLeaks();
  222. }
  223.  
  224. #endif // _AFX_NO_DEBUG_CRT
  225. #endif // _DEBUG
  226.  
  227. /////////////////////////////////////////////////////////////////////////////
  228. // Non-diagnostic memory routines
  229.  
  230. int AFX_CDECL AfxNewHandler(size_t /* nSize */)
  231. {
  232.     AfxThrowMemoryException();
  233.     return 0;
  234. }
  235.  
  236. #pragma warning(disable: 4273)
  237.  
  238. _PNH AFXAPI AfxGetNewHandler(void)
  239. {
  240.     AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  241.     return pState->m_pfnNewHandler;
  242. }
  243.  
  244. _PNH AFXAPI AfxSetNewHandler(_PNH pfnNewHandler)
  245. {
  246.     AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  247.     _PNH pfnOldHandler = pState->m_pfnNewHandler;
  248.     pState->m_pfnNewHandler = pfnNewHandler;
  249.     return pfnOldHandler;
  250. }
  251.  
  252. static const _PNH _pfnUninitialized = (_PNH)-1;
  253.  
  254. void* __cdecl operator new(size_t nSize)
  255. {
  256.     void* pResult;
  257.     _PNH pfnNewHandler = _pfnUninitialized;
  258.     for (;;)
  259.     {
  260. #if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
  261.         pResult = _malloc_dbg(nSize, _NORMAL_BLOCK, NULL, 0);
  262. #else
  263.         pResult = malloc(nSize);
  264. #endif
  265.         if (pResult != NULL)
  266.             return pResult;
  267.  
  268.         if (pfnNewHandler == _pfnUninitialized)
  269.         {
  270.             AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  271.             pfnNewHandler = pState->m_pfnNewHandler;
  272.         }
  273.         if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0)
  274.             break;
  275.     }
  276.     return pResult;
  277. }
  278.  
  279. void __cdecl operator delete(void* p)
  280. {
  281. #if !defined(_AFX_NO_DEBUG_CRT) && defined(_DEBUG)
  282.         _free_dbg(p, _NORMAL_BLOCK);
  283. #else
  284.         free(p);
  285. #endif
  286. }
  287.  
  288. #ifdef _DEBUG
  289.  
  290. void* __cdecl operator new(size_t nSize, int nType, LPCSTR lpszFileName, int nLine)
  291. {
  292. #ifdef _AFX_NO_DEBUG_CRT
  293.     UNUSED_ALWAYS(nType);
  294.     UNUSED_ALWAYS(lpszFileName);
  295.     UNUSED_ALWAYS(nLine);
  296.     return ::operator new(nSize);
  297. #else
  298.     void* pResult;
  299.     _PNH pfnNewHandler = _pfnUninitialized;
  300.     for (;;)
  301.     {
  302.         pResult = _malloc_dbg(nSize, nType, lpszFileName, nLine);
  303.         if (pResult != NULL)
  304.             return pResult;
  305.  
  306.         if (pfnNewHandler == _pfnUninitialized)
  307.         {
  308.             AFX_MODULE_THREAD_STATE* pState = AfxGetModuleThreadState();
  309.             pfnNewHandler = pState->m_pfnNewHandler;
  310.         }
  311.         if (pfnNewHandler == NULL || (*pfnNewHandler)(nSize) == 0)
  312.             break;
  313.     }
  314.     return pResult;
  315. #endif
  316. }
  317.  
  318. #endif //_DEBUG
  319.  
  320. /////////////////////////////////////////////////////////////////////////////
  321.