⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbgheap.c

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 C
📖 第 1 页 / 共 4 页
字号:
*       FALSE otherwise
*
*******************************************************************************/
_CRTIMP int __cdecl _CrtIsValidPointer(
        const void * pv,
        unsigned int nBytes,
        int bReadWrite
        )
{
        return (
            pv != NULL
#ifdef _WIN32
            && !IsBadReadPtr(pv, nBytes) &&
            (!bReadWrite || !IsBadWritePtr((LPVOID)pv, nBytes))
#endif  /* _WIN32 */
            );
}

/***
*int _CrtIsValidHeapPointer() - verify pointer is from 'local' heap
*
*Purpose:
*       Verify pointer is not only a valid pointer but also that it is from
*       the 'local' heap. Pointers from another copy of the C runtime (even in the
*       same process) will be caught.
*
*Entry:
*       const void * pUserData     - pointer of interest
*
*Return:
*       TRUE - if valid and from local heap
*       FALSE otherwise
*
*******************************************************************************/
_CRTIMP int __cdecl _CrtIsValidHeapPointer(
        const void * pUserData
        )
{
#ifndef WINHEAP
        int i;
        void * base;
#endif  /* WINHEAP */

        if (!pUserData)
            return FALSE;

        if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), TRUE))
            return FALSE;

#ifdef WINHEAP

        if ( __active_heap == __V6_HEAP )
        {
            PHEADER     pHeader;
            if (pHeader = __sbh_find_block(pHdr(pUserData)))
            {
                return __sbh_verify_block(pHeader, pHdr(pUserData));
            }
            else if ( (_osver & 0x8000) != 0 )
                return TRUE;
            else
                return HeapValidate( _crtheap, 0, pHdr(pUserData) );
        }
        else if ( __active_heap == __V5_HEAP )
        {
            __old_sbh_region_t * preg;
            __old_sbh_page_t *   ppage;
            __old_page_map_t *   pmap;
            if ( (pmap = __old_sbh_find_block( pHdr(pUserData), &preg, &ppage )) !=
                 NULL )
            {
                if ( *pmap )
                    return TRUE;
                else
                    return FALSE;
            }
            else if ( (_osver & 0x8000) != 0 )
                return TRUE;
            else
                return HeapValidate( _crtheap, 0, pHdr(pUserData) );
        }
        else    //  __active_heap == _SYSTEM_HEAP
            return HeapValidate( _crtheap, 0, pHdr(pUserData) );

#else  /* WINHEAP */

        /*
         * Go through the heap regions and see if the pointer lies within one
         * of the regions of the local heap.
         *
         * Pointers from non-local heaps cannot be handled. For example, a
         * non-local pointer may come from a DLL that has the CRT linked-in.
         *
         */

#ifdef _WIN32
        for (i = 0; (base = _heap_regions[i]._regbase) != NULL &&
                i < _HEAP_REGIONMAX; i++)
        {
            if (pUserData >= base && pUserData <
                    (void *)(((char *)base)+_heap_regions[i]._currsize))
                return TRUE;
        }
#else  /* _WIN32 */
        {
            struct _heap_region_ *pHeapRegions
                = (struct _heap_region_ *)(*hHeapRegions);

            for (i = 0; (base = (pHeapRegions+i)->_regbase) != NULL &&
                        i < _HEAP_REGIONMAX; i++)
            {
                if (pUserData >= base && pUserData <
                        (void *)(((char *)base)+(pHeapRegions+i)->_currsize))
                    return TRUE;
            }
        }
#endif  /* _WIN32 */

        return FALSE;

#endif  /* WINHEAP */
}


/***
*int _CrtIsMemoryBlock() - verify memory block is debug heap block
*
*Purpose:
*       verify memory block is debug heap block
*
*Entry:
*       const void *    pUserData       - start of memory block
*       unsigned int    nBytes          - size of memory block
*       long * plRequestNumber          - if !NULL, set to request number
*       char **         pszFileName     - if !NULL, set to file name
*       int *           pnLine          - if !NULL, set to line number
*
*Return:
*       TRUE - if debug memory heap address
*       FALSE otherwise
*
*******************************************************************************/
_CRTIMP int __cdecl _CrtIsMemoryBlock(
        const void * pUserData,
        unsigned int nBytes,
        long * plRequestNumber,
        char ** pszFileName,
        int * pnLine
        )
{
        _CrtMemBlockHeader * pHead;
        int retval;

        if (!_CrtIsValidHeapPointer(pUserData))
            return FALSE;

#ifdef _MT
        _mlock(_HEAP_LOCK);         /* block other threads */
        __try {
#endif  /* _MT */

        pHead = pHdr(pUserData);

        if (_BLOCK_TYPE_IS_VALID(pHead->nBlockUse) &&
            _CrtIsValidPointer(pUserData, nBytes, TRUE) &&
            pHead->nDataSize == nBytes &&
            pHead->lRequest <= _lRequestCurr
           )
        {
            if (plRequestNumber != NULL)
                *plRequestNumber = pHead->lRequest;
            if (pszFileName != NULL)
                *pszFileName = pHead->szFileName;
            if (pnLine != NULL)
                *pnLine = pHead->nLine;

            retval = TRUE;
        }
        else
            retval = FALSE;

#ifdef _MT
        }
        __finally {
            _munlock(_HEAP_LOCK);   /* release other threads */
        }
#endif  /* _MT */

        return retval;
}


/*---------------------------------------------------------------------------
 *
 * Memory state
 *
 --------------------------------------------------------------------------*/


/***
*_CRT_DUMP_CLIENT _CrtSetDumpClient() - set client dump routine
*
*Purpose:
*       set client dump routine
*
*Entry:
*       _CRT_DUMP_CLIENT pfnNewDumpClient - new dump routine
*
*Exit:
*       return previous dump routine
*
*Exceptions:
*
*******************************************************************************/
_CRTIMP _CRT_DUMP_CLIENT __cdecl _CrtSetDumpClient(
        _CRT_DUMP_CLIENT pfnNewDump
        )
{
        _CRT_DUMP_CLIENT pfnOldDump = _pfnDumpClient;
        _pfnDumpClient = pfnNewDump;
        return pfnOldDump;
}


/***
*_CrtMemState * _CrtMemStateCheckpoint() - checkpoint current memory state
*
*Purpose:
*       checkpoint current memory state
*
*Entry:
*       _CrtMemState * state - state structure to fill in, will be
*       allocated if NULL
*
*Return:
*       current memory state
*
*******************************************************************************/
_CRTIMP void __cdecl _CrtMemCheckpoint(
        _CrtMemState * state
        )
{
        int use;
        _CrtMemBlockHeader * pHead;

        if (state == NULL)
        {
            _RPT0(_CRT_WARN, "_CrtMemCheckPoint: NULL state pointer.\n");
            return;
        }

#ifdef _MT
        _mlock(_HEAP_LOCK);         /* block other threads */
        __try {
#endif  /* _MT */

        state->pBlockHeader = _pFirstBlock;
        for (use = 0; use < _MAX_BLOCKS; use++)
            state->lCounts[use] = state->lSizes[use] = 0;

        for (pHead = _pFirstBlock; pHead != NULL; pHead = pHead->pBlockHeaderNext)
        {
            if (_BLOCK_TYPE(pHead->nBlockUse) >= 0 && _BLOCK_TYPE(pHead->nBlockUse) < _MAX_BLOCKS)
            {
                state->lCounts[_BLOCK_TYPE(pHead->nBlockUse)]++;
                state->lSizes[_BLOCK_TYPE(pHead->nBlockUse)] += pHead->nDataSize;
            }
            else
            {
                _RPT1(_CRT_WARN, "Bad memory block found at 0x%08X.\n", (BYTE *)pHead);
            }
        }

        state->lHighWaterCount = _lMaxAlloc;
        state->lTotalCount = _lTotalAlloc;

#ifdef _MT
        }
        __finally {
            _munlock(_HEAP_LOCK);   /* release other threads */
        }
#endif  /* _MT */
}


/***
*int _CrtMemDifference() - compare two memory states
*
*Purpose:
*       compare two memory states
*
*Entry:
*       _CrtMemState * state - return memory state difference
*       _CrtMemState * oldState - earlier memory state
*       _CrtMemState * newState - later memory state
*
*Return:
*       TRUE if difference
*       FALSE otherwise
*
*******************************************************************************/
_CRTIMP int __cdecl _CrtMemDifference(
        _CrtMemState * state,
        const _CrtMemState * oldState,
        const _CrtMemState * newState
        )
{
        int use;
        int bSignificantDifference = FALSE;

        if (state == NULL || oldState == NULL || newState == NULL)
        {
            _RPT0(_CRT_WARN, "_CrtMemDifference: NULL state pointer.\n");
            return bSignificantDifference;
        }

        for (use = 0; use < _MAX_BLOCKS; use++)
        {
            state->lSizes[use] = newState->lSizes[use] - oldState->lSizes[use];
            state->lCounts[use] = newState->lCounts[use] - oldState->lCounts[use];

            if (    (state->lSizes[use] != 0 || state->lCounts[use] != 0) &&
                     use != _FREE_BLOCK &&
                    (use != _CRT_BLOCK ||
                    (use == _CRT_BLOCK && (_crtDbgFlag & _CRTDBG_CHECK_CRT_DF)))
                    )
                bSignificantDifference = TRUE;
        }
        state->lHighWaterCount = newState->lHighWaterCount - oldState->lHighWaterCount;
        state->lTotalCount = newState->lTotalCount - oldState->lTotalCount;
        state->pBlockHeader = NULL;

        return bSignificantDifference;
}

#define MAXPRINT 16

static void __cdecl _printMemBlockData(
        _CrtMemBlockHeader * pHead
        )
{
        int i;
        unsigned char ch;
        unsigned char printbuff[MAXPRINT+1];
        unsigned char valbuff[MAXPRINT*3+1];

        for (i = 0; i < min((int)pHead->nDataSize, MAXPRINT); i++)
        {
            ch = pbData(pHead)[i];
            printbuff[i] = isprint(ch) ? ch : ' ';
            sprintf(&valbuff[i*3], "%.2X ", ch);
        }
        printbuff[i] = '\0';

        _RPT2(_CRT_WARN, " Data: <%s> %s\n", printbuff, valbuff);
}


/***
*void _CrtMemDumpAllObjectsSince() - dump all objects since memory state
*
*Purpose:
*       dump all objects since memory state
*
*Entry:
*       _CrtMemState * state - dump since this state
*
*Return:
*       void
*
*******************************************************************************/
_CRTIMP void __cdecl _CrtMemDumpAllObjectsSince(
        const _CrtMemState * state
        )
{
        _CrtMemBlockHeader * pHead;
        _CrtMemBlockHeader * pStopBlock = NULL;

#ifdef _MT
        _mlock(_HEAP_LOCK);         /* block other threads */
        __try {
#endif  /* _MT */

        _RPT0(_CRT_WARN, "Dumping objects ->\n");

        if (state)
            pStopBlock = state->pBlockHeader;

        for (pHead = _pFirstBlock; pHead != NULL && pHead != pStopBlock;
            pHead = pHead->pBlockHeaderNext)
        {
            if (_BLOCK_TYPE(pHead->nBlockUse) == _IGNORE_BLOCK ||
                _BLOCK_TYPE(pHead->nBlockUse) == _FREE_BLOCK ||
                (_BLOCK_TYPE(pHead->nBlockUse) == _CRT_BLOCK &&
               !(_crtDbgFlag & _CRTDBG_CHECK_CRT_DF))
               )
            {
                /* ignore it for dumping */
            }
            else {
                if (pHead->szFileName != NULL)
                {
                    if (!_CrtIsValidPointer(pHead->szFileName, 1, FALSE))
                        _RPT1(_CRT_WARN, "#File Error#(%d) : ", pHead->nLine);
                    else
                        _RPT2(_CRT_WARN, "%hs(%d) : ", pHead->szFileName, pHead->nLine);
                }

                _RPT1(_CRT_WARN, "{%ld} ", pHead->lRequest);

                if (_BLOCK_TYPE(pHead->nBlockUse) == _CLIENT_BLOCK)
                {
                    _RPT3(_CRT_WARN, "client block at 0x%08X, subtype %x, %u bytes long.\n",
                        (BYTE *)pbData(pHead), _BLOCK_SUBTYPE(pHead->nBlockUse), pHead->nDataSize);

                    if (_pfnDumpClient)
                        (*_pfnDumpClient)( (void *) pbData(pHead), pHead->nDataSize);
                    else
                        _printMemBlockData(pHead);
                }
                else if (pHead->nBlockUse == _NORMAL_BLOCK)
                {
                    _RPT2(_CRT_WARN, "normal block at 0x%08X, %u bytes long.\n",
                        (BYTE *)pbData(pHead), pHead->nDataSize);

                    _printMemBlockData(pHead);
                }
                else if (_BLOCK_TYPE(pHead->nBlockUse) == _CRT_BLOCK)
                {
                    _RPT3(_CRT_WARN, "crt block at 0x%08X, subtype %x, %u bytes long.\n",
                        (BYTE *)pbData(pHead), _BLOCK_SUBTYPE(pHead->nBlockUse), pHead->nDataSize);

                    _printMemBlockData(pHead);
                }
            }
        }
#ifdef _MT
        }
        __finally {
            _munlock(_HEAP_LOCK);   /* release other threads */
        }
#endif  /* _MT */

        _RPT0(_CRT_WARN, "Object dump complete.\n");
}


/***
*void _CrtMemDumpMemoryLeaks() - dump all objects still in heap
*
*Purpose:
*       dump all objects still in heap. used to detect memory leaks over the
*       life of a program
*
*Entry:
*       void
*
*Return:
*       TRUE if memory leaks
*       FALSE otherwise
*
*******************************************************************************/
_CRTIMP int __cdecl _CrtDumpMemoryLeaks(
        void
        )
{
        /* only dump leaks when there are in fact leaks */
        _CrtMemState msNow;

        _CrtMemCheckpoint(&msNow);

        if (msNow.lCounts[_CLIENT_BLOCK] != 0 ||
            msNow.lCounts[_NORMAL_BLOCK] != 0 ||
            (_crtDbgFlag & _CRTDBG_CHECK_CRT_DF &&
            msNow.lCounts[_CRT_BLOCK] != 0)
           )
        {
            /* difference detected: dump objects since start. */
            _RPT0(_CRT_WARN, "Detected memory leaks!\n");

            _CrtMemDumpAllObjectsSince(NULL);
            return TRUE;
        }

        return FALSE;   /* no leaked objects */
}


/***
*_CrtMemState * _CrtMemDumpStatistics() - dump memory state
*
*Purpose:
*       dump memory state
*
*Entry:
*       _CrtMemState * state - dump this state
*
*Return:
*       void
*
*******************************************************************************/
_CRTIMP void __cdecl _CrtMemDumpStatistics(
        const _CrtMemState * state
        )
{
        int use;

        if (state == NULL)
            return;

        for (use = 0; use < _MAX_BLOCKS; use++)
        {
            _RPT3(_CRT_WARN, "%ld bytes in %ld %hs Blocks.\n",
                state->lSizes[use], state->lCounts[use], szBlockUseName[use]);
        }

        _RPT1(_CRT_WARN, "Largest number used: %ld bytes.\n", state->lHighWaterCount);
        _RPT1(_CRT_WARN, "Total allocations: %ld bytes.\n", state->lTotalCount);
}


#endif  /* _DEBUG */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -