急 那能找出VC6.0的 dbgheap.c 源码

急!! 那能找到VC6.0的 dbgheap.c 源码!
_CrtIsVolidHeapPointer(pUserData)
dbgheap.c line 1011

new 的类, 调用delete释放时出错, 调用折构函数时出错的, 跟踪到 scalar deleting destructor()

怎么也查不出为什么内存出错。 于是想看 dbgheap.c 源码。




------解决方案--------------------
装VC6的时候装了源码的话就能跟踪到了,去找一个完整的VC6吧,VS6.0企业版应该是3CD的

不过楼主方向错了,99%不是VC6的bug,即便是你又能怎样?

delete失败,最典型的原因是内存越界和指针绝对值改变
------解决方案--------------------
C/C++ code

/***
*dbgheap.c - Debug CRT Heap Functions
*
*       Copyright (c) 1988-1997, 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
        )
{
        return _nh_malloc_dbg(nSize, _newmode, _NORMAL_BLOCK, NULL, 0);
}

/***
*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
        )
{
        return _nh_malloc_dbg(nSize, _newmode, nBlockUse, szFileName, nLine);
}

/***
*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 (;;)
        {
            /* lock the heap
             */
            _mlock(_HEAP_LOCK);

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

            /* unlock the heap
             */
            _munlock(_HEAP_LOCK);

            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);
}