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

📄 dbgheap.c

📁 c语言编程软件vc6.0中文绿色版_vc6.0官方下载
💻 C
📖 第 1 页 / 共 4 页
字号:
/***
*dbgheap.c - Debug CRT Heap Functions
*
*       Copyright (c) 1988-1998, Microsoft Corporation. All rights reserved.
*
*Purpose:
*       Defines debug versions of heap functions.
*
*******************************************************************************/

#ifdef _DEBUG

#ifdef _WIN32
#include <windows.h>
#include <winheap.h>
#else  /* _WIN32 */
#include <memory.h>
#include <string.h>
#define FALSE 0
#define TRUE  1
#define BYTE char
#endif  /* _WIN32 */

#include <ctype.h>
#include <dbgint.h>
#ifndef WINHEAP
#include <heap.h>
#endif  /* WINHEAP */
#include <internal.h>
#include <limits.h>
#include <malloc.h>
#include <mtdll.h>
#include <stdio.h>
#include <stdlib.h>


/*---------------------------------------------------------------------------
 *
 * Heap management
 *
 --------------------------------------------------------------------------*/

#ifdef _MAC
extern Handle hHeapRegions;
#endif  /* _MAC */

#define IGNORE_REQ  0L              /* Request number for ignore block */
#define IGNORE_LINE 0xFEDCBABC      /* Line number for ignore block */


/*
 * Bitfield flag that controls CRT heap behavior --
 * default is to record all allocations (_CRTDBG_ALLOC_MEM_DF)
 */
int _crtDbgFlag = _CRTDBG_ALLOC_MEM_DF;

static long _lRequestCurr = 1;      /* Current request number */

_CRTIMP long _crtBreakAlloc = -1L;          /* Break on allocation by request number */

static unsigned long _lTotalAlloc;  /* Grand total - sum of all allocations */
static unsigned long _lCurAlloc;    /* Total amount currently allocated */
static unsigned long _lMaxAlloc;    /* Largest ever allocated at once */

/*
 * The following values are non-zero, constant, odd, large, and atypical
 *      Non-zero values help find bugs assuming zero filled data.
 *      Constant values are good so that memory filling is deterministic
 *          (to help make bugs reproducable).  Of course it is bad if
 *          the constant filling of weird values masks a bug.
 *      Mathematically odd numbers are good for finding bugs assuming a cleared
 *          lower bit, as well as useful for trapping on the Mac.
 *      Large numbers (byte values at least) are less typical, and are good
 *          at finding bad addresses.
 *      Atypical values (i.e. not too often) are good since they typically
 *          cause early detection in code.
 *      For the case of no-man's land and free blocks, if you store to any
 *          of these locations, the memory integrity checker will detect it.
 */

static unsigned char _bNoMansLandFill = 0xFD;   /* fill no-man's land with this */
static unsigned char _bDeadLandFill   = 0xDD;   /* fill free objects with this */
static unsigned char _bCleanLandFill  = 0xCD;   /* fill new objects with this */

static _CrtMemBlockHeader * _pFirstBlock;
static _CrtMemBlockHeader * _pLastBlock;

_CRT_DUMP_CLIENT _pfnDumpClient;


#if _FREE_BLOCK != 0 || _NORMAL_BLOCK != 1 || _CRT_BLOCK != 2 || _IGNORE_BLOCK != 3 || _CLIENT_BLOCK != 4
#error Block numbers have changed !
#endif  /* _FREE_BLOCK != 0 || _NORMAL_BLOCK != 1 || _CRT_BLOCK != 2 || _IGNORE_BLOCK != 3 || _CLIENT_BLOCK != 4 */

static char * szBlockUseName[_MAX_BLOCKS] = {
        "Free",
        "Normal",
        "CRT",
        "Ignore",
        "Client",
        };

int __cdecl CheckBytes(unsigned char *, unsigned char, size_t);


/***
*void *malloc() - Get a block of memory from the debug heap
*
*Purpose:
*       Allocate of block of memory of at least size bytes from the heap and
*       return a pointer to it.
*
*       Allocates 'normal' memory block.
*
*Entry:
*       size_t          nSize       - size of block requested
*
*Exit:
*       Success:  Pointer to memory block
*       Failure:  NULL (or some error value)
*
*Exceptions:
*
*******************************************************************************/

_CRTIMP void * __cdecl malloc (
        size_t nSize
        )
{
        void *res = _nh_malloc_dbg(nSize, _newmode, _NORMAL_BLOCK, NULL, 0);

        return res;
}

/***
*void * _malloc_dbg() - Get a block of memory from the debug heap
*
*Purpose:
*       Allocate of block of memory of at least size bytes from the heap and
*       return a pointer to it.
*
*       Allocates any type of supported memory block.
*
*Entry:
*       size_t          nSize       - size of block requested
*       int             nBlockUse   - block type
*       char *          szFileName  - file name
*       int             nLine       - line number
*
*Exit:
*       Success:  Pointer to memory block
*       Failure:  NULL (or some error value)
*
*Exceptions:
*
*******************************************************************************/

_CRTIMP void * __cdecl _malloc_dbg (
        size_t nSize,
        int nBlockUse,
        const char * szFileName,
        int nLine
        )
{
        void *res = _nh_malloc_dbg(nSize, _newmode, nBlockUse, szFileName, nLine);
        return res;
}

/***
*void * _nh_malloc() - Get a block of memory from the debug heap
*
*Purpose:
*       Allocate of block of memory of at least size bytes from the debug
*       heap and return a pointer to it. Assumes heap already locked.
*
*       If no blocks available, call new handler.
*
*       Allocates 'normal' memory block.
*
*Entry:
*       size_t          nSize       - size of block requested
*       int             nhFlag      - TRUE if new handler function
*
*Exit:
*       Success:  Pointer to (user portion of) memory block
*       Failure:  NULL
*
*Exceptions:
*
*******************************************************************************/

void * __cdecl _nh_malloc (
        size_t nSize,
        int nhFlag
        )
{
        return _nh_malloc_dbg(nSize, nhFlag, _NORMAL_BLOCK, NULL, 0);
}


/***
*void * _nh_malloc_dbg() - Get a block of memory from the debug heap
*
*Purpose:
*       Allocate of block of memory of at least size bytes from the debug
*       heap and return a pointer to it. Assumes heap already locked.
*
*       If no blocks available, call new handler.
*
*       Allocates any type of supported memory block.
*
*Entry:
*       size_t          nSize       - size of block requested
*       int             nhFlag      - TRUE if new handler function
*       int             nBlockUse   - block type
*       char *          szFileName  - file name
*       int             nLine       - line number
*
*Exit:
*       Success:  Pointer to (user portion of) memory block
*       Failure:  NULL
*
*Exceptions:
*
*******************************************************************************/

void * __cdecl _nh_malloc_dbg (
        size_t nSize,
        int nhFlag,
        int nBlockUse,
        const char * szFileName,
        int nLine
        )
{
        void * pvBlk;

        for (;;)
        {
#ifdef _MT
            /* lock the heap
             */
            _mlock(_HEAP_LOCK);
            __try {
#endif  /* _MT */

            /* do the allocation
             */
            pvBlk = _heap_alloc_dbg(nSize, nBlockUse, szFileName, nLine);

#ifdef _MT
            }
            __finally {
                /* unlock the heap
                 */
                _munlock(_HEAP_LOCK);
            }
#endif  /* _MT */

            if (pvBlk || nhFlag == 0)
                return pvBlk;

            /* call installed new handler */
            if (!_callnewh(nSize))
                return NULL;

            /* new handler was successful -- try to allocate again */
        }
}

/***
*void * _heap_alloc() - does actual allocation
*
*Purpose:
*       Does heap allocation.
*
*       Allocates 'normal' memory block.
*
*Entry:
*       size_t          nSize       - size of block requested
*
*Exit:
*       Success:  Pointer to (user portion of) memory block
*       Failure:  NULL
*
*Exceptions:
*
*******************************************************************************/

void * __cdecl _heap_alloc(
        size_t nSize
        )
{
        return _heap_alloc_dbg(nSize, _NORMAL_BLOCK, NULL, 0);
}

/***
*void * _heap_alloc_dbg() - does actual allocation
*
*Purpose:
*       Does heap allocation.
*
*       Allocates any type of supported memory block.
*
*Entry:
*       size_t          nSize       - size of block requested
*       int             nBlockUse   - block type
*       char *          szFileName  - file name
*       int             nLine       - line number
*
*Exit:
*       Success:  Pointer to (user portion of) memory block
*       Failure:  NULL
*
*Exceptions:
*
*******************************************************************************/

void * __cdecl _heap_alloc_dbg(
        size_t nSize,
        int nBlockUse,
        const char * szFileName,
        int nLine
        )
{
        long lRequest;
        size_t blockSize;
        int fIgnore = FALSE;
        _CrtMemBlockHeader * pHead;

        /* verify heap before allocation */
        if (_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF)
            _ASSERTE(_CrtCheckMemory());

        lRequest = _lRequestCurr;

        /* break into debugger at specific memory allocation */
        if (lRequest == _crtBreakAlloc)
            _CrtDbgBreak();

        /* forced failure */
        if (!(*_pfnAllocHook)(_HOOK_ALLOC, NULL, nSize, nBlockUse, lRequest, szFileName, nLine))
        {
            if (szFileName)
                _RPT2(_CRT_WARN, "Client hook allocation failure at file %hs line %d.\n",
                    szFileName, nLine);
            else
                _RPT0(_CRT_WARN, "Client hook allocation failure.\n");

            return NULL;
        }

        /* cannot ignore CRT allocations */
        if (_BLOCK_TYPE(nBlockUse) != _CRT_BLOCK &&
            !(_crtDbgFlag & _CRTDBG_ALLOC_MEM_DF))
            fIgnore = TRUE;

        /* Diagnostic memory allocation from this point on */

        if (nSize > (size_t)_HEAP_MAXREQ ||
            nSize + nNoMansLandSize + sizeof(_CrtMemBlockHeader) > (size_t)_HEAP_MAXREQ)
        {
            _RPT1(_CRT_ERROR, "Invalid allocation size: %u bytes.\n", nSize);
            return NULL;
        }

        if (!_BLOCK_TYPE_IS_VALID(nBlockUse))
        {
            _RPT0(_CRT_ERROR, "Error: memory allocation: bad memory block type.\n");
        }

        blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;

#ifndef WINHEAP
        /* round requested size */
        blockSize = _ROUND2(blockSize, _GRANULARITY);
#endif  /* WINHEAP */

        pHead = (_CrtMemBlockHeader *)_heap_alloc_base(blockSize);

        if (pHead == NULL)
            return NULL;

        /* commit allocation */
        ++_lRequestCurr;

        if (fIgnore)
        {
            pHead->pBlockHeaderNext = NULL;
            pHead->pBlockHeaderPrev = NULL;
            pHead->szFileName = NULL;
            pHead->nLine = IGNORE_LINE;
            pHead->nDataSize = nSize;
            pHead->nBlockUse = _IGNORE_BLOCK;
            pHead->lRequest = IGNORE_REQ;
        }
        else {
            /* keep track of total amount of memory allocated */
            _lTotalAlloc += nSize;
            _lCurAlloc += nSize;

            if (_lCurAlloc > _lMaxAlloc)
                _lMaxAlloc = _lCurAlloc;

            if (_pFirstBlock)
                _pFirstBlock->pBlockHeaderPrev = pHead;
            else
                _pLastBlock = pHead;

            pHead->pBlockHeaderNext = _pFirstBlock;
            pHead->pBlockHeaderPrev = NULL;
            pHead->szFileName = (char *)szFileName;
            pHead->nLine = nLine;
            pHead->nDataSize = nSize;
            pHead->nBlockUse = nBlockUse;
            pHead->lRequest = lRequest;

            /* link blocks together */
            _pFirstBlock = pHead;
        }

        /* fill in gap before and after real block */
        memset((void *)pHead->gap, _bNoMansLandFill, nNoMansLandSize);
        memset((void *)(pbData(pHead) + nSize), _bNoMansLandFill, nNoMansLandSize);

        /* fill data with silly value (but non-zero) */
        memset((void *)pbData(pHead), _bCleanLandFill, nSize);

        return (void *)pbData(pHead);
}


/***
*void * calloc() - Get a block of memory from the debug heap, init to 0
*
*Purpose:
*       Allocate of block of memory of at least size bytes from the debug
*       heap and return a pointer to it.
*
*       Allocates 'normal' memory block.
*
*Entry:
*       size_t nNum     - number of elements in the array
*       size_t nSize - size of each element
*
*Exit:
*       Success:  Pointer to (user portion of) memory block
*       Failure:  NULL
*
*Exceptions:
*
*******************************************************************************/
_CRTIMP void * __cdecl calloc(
        size_t nNum,
        size_t nSize
        )
{
        void *res = _calloc_dbg(nNum, nSize, _NORMAL_BLOCK, NULL, 0);

        return res;
}


/***
*void * _calloc_dbg() - Get a block of memory from the debug heap, init to 0
*                    - with info
*
*Purpose:
*       Allocate of block of memory of at least size bytes from the debug
*       heap and return a pointer to it.
*
*       Allocates any type of supported memory block.
*
*Entry:
*       size_t          nNum        - number of elements in the array
*       size_t          nSize       - size of each element
*       int             nBlockUse   - block type
*       char *          szFileName  - file name
*       int             nLine       - line number
*
*Exit:
*       Success:  Pointer to (user portion of) memory block
*       Failure:  NULL
*
*Exceptions:
*
*******************************************************************************/

_CRTIMP void * __cdecl _calloc_dbg(
        size_t nNum,
        size_t nSize,
        int nBlockUse,
        const char * szFileName,
        int nLine
        )
{
        void * pvBlk;
        unsigned char *pStart;
        unsigned char *pLast;

        nSize *= nNum;

        /*
         * try to malloc the requested space
         */

        pvBlk = _malloc_dbg(nSize, nBlockUse, szFileName, nLine);

        /*
         * If malloc() succeeded, initialize the allocated space to zeros.
         * Note that unlike _calloc_base, exactly nNum bytes are set to zero.
         */

        if ( pvBlk != NULL )
        {
            pStart = (unsigned char *)pvBlk;
            pLast = pStart + nSize;
            while ( pStart < pLast )
                 *(pStart++) = 0;
        }

        return(pvBlk);
}


/***

⌨️ 快捷键说明

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