dbgheap.c
来自「C语言库函数的原型,有用的拿去」· C语言 代码 · 共 2,046 行 · 第 1/5 页
C
2,046 行
/* Diagnostic memory allocation from this point on */
if (nSize > (size_t)(_HEAP_MAXREQ - nNoMansLandSize - sizeof(_CrtMemBlockHeader)))
{
_RPT1(_CRT_ERROR, "Invalid allocation size: %Iu bytes.\n", nSize);
if (errno_tmp)
{
*errno_tmp = ENOMEM;
}
}
else
{
if (!_BLOCK_TYPE_IS_VALID(nBlockUse))
{
_RPT0(_CRT_ERROR, "Error: memory allocation: bad memory block type.\n");
}
blockSize = sizeof(_CrtMemBlockHeader) + nSize + nNoMansLandSize;
RTCCALLBACK(_RTC_FuncCheckSet_hook,(0));
pHead = (_CrtMemBlockHeader *)_heap_alloc_base(blockSize);
if (pHead == NULL)
{
if (errno_tmp)
{
*errno_tmp = ENOMEM;
}
RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));
}
else
{
/* 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 */
if (SIZE_MAX - _lTotalAlloc > nSize)
{
_lTotalAlloc += nSize;
}
else
{
_lTotalAlloc = SIZE_MAX;
}
_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);
RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));
retval=(void *)pbData(pHead);
}
}
}
}
__finally {
/* unlock the heap
*/
_munlock(_HEAP_LOCK);
}
return retval;
}
/***
*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:
*
*******************************************************************************/
extern "C" void * __cdecl _heap_alloc_dbg(
size_t nSize,
int nBlockUse,
const char * szFileName,
int nLine
)
{
int errno_tmp = 0;
void * retval = _heap_alloc_dbg_impl(nSize, nBlockUse, szFileName, nLine, &errno_tmp);
if ( retval == NULL && errno_tmp != 0 && _errno())
{
errno = errno_tmp; // recall, #define errno *_errno()
}
return retval;
}
/***
*void * _calloc_dbg_impl() - 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
* int * errno_tmp - pointer of the temporary errno
*
*Exit:
* Success: Pointer to (user portion of) memory block
* Failure: NULL
*
*Exceptions:
*
*******************************************************************************/
extern "C" void * __cdecl _calloc_dbg_impl(
size_t nNum,
size_t nSize,
int nBlockUse,
const char * szFileName,
int nLine,
int * errno_tmp
)
{
void * pvBlk;
/* ensure that (nSize * nNum) does not overflow */
if (nNum > 0)
{
_VALIDATE_RETURN_NOEXC((_HEAP_MAXREQ / nNum) >= nSize, ENOMEM, NULL);
}
nSize *= nNum;
/*
* try to malloc the requested space
*/
pvBlk = _nh_malloc_dbg_impl(nSize, _newmode, nBlockUse, szFileName, nLine, errno_tmp);
/*
* If malloc() succeeded, initialize the allocated space to zeros.
* Note that unlike _calloc_base, exactly nNum bytes are set to zero.
*/
if ( pvBlk != NULL )
{
memset(pvBlk, 0, nSize);
}
RTCCALLBACK(_RTC_Allocate_hook, (pvBlk, nSize, 0));
return(pvBlk);
}
/***
*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:
*
*******************************************************************************/
extern "C" _CRTIMP void * __cdecl _calloc_dbg(
size_t nNum,
size_t nSize,
int nBlockUse,
const char * szFileName,
int nLine
)
{
int errno_tmp = 0;
void * pvBlk = _calloc_dbg_impl(nNum, nSize, nBlockUse, szFileName, nLine, &errno_tmp);
if ( pvBlk == NULL && errno_tmp != 0 && _errno())
{
errno = errno_tmp; // recall, #define errno *_errno()
}
return pvBlk;
}
/***
*static void * realloc_help() - does all the work for _realloc and _expand
*
*Purpose:
* Helper function for _realloc and _expand.
*
*Entry:
* void * pUserData - pointer previously allocated block
* size_t * pnNewSize - requested size for the re-allocated block
* changed to actual size during call
* int nBlockUse - block type
* char * szFileName - file name
* int nLine - line number
* int fRealloc - TRUE when _realloc, FALSE when _expand
*
*Exit:
* Success: Pointer to (user portion of) memory block
* Failure: NULL
*
*Exceptions:
*
*******************************************************************************/
extern "C" static void * __cdecl realloc_help(
void * pUserData,
size_t * pnNewSize,
int nBlockUse,
const char * szFileName,
int nLine,
int fRealloc
)
{
long lRequest;
int fIgnore = FALSE;
unsigned char *pUserBlock;
_CrtMemBlockHeader * pOldBlock;
_CrtMemBlockHeader * pNewBlock;
size_t nNewSize = *pnNewSize;
/*
* ANSI: realloc(NULL, newsize) is equivalent to malloc(newsize)
*/
if (pUserData == NULL)
{
return _malloc_dbg(nNewSize, nBlockUse, szFileName, nLine);
}
/*
* ANSI: realloc(pUserData, 0) is equivalent to free(pUserData)
* (except that NULL is returned)
*/
if (fRealloc && nNewSize == 0)
{
_free_dbg(pUserData, nBlockUse);
return NULL;
}
/* verify heap before re-allocation */
if (check_frequency > 0)
if (check_counter == (check_frequency - 1))
{
_ASSERTE(_CrtCheckMemory());
check_counter = 0;
}
else
check_counter++;
lRequest = _lRequestCurr;
if (_crtBreakAlloc != -1L && lRequest == _crtBreakAlloc)
_CrtDbgBreak(); /* break into debugger at specific memory leak */
/* forced failure */
if ((_pfnAllocHook) && !(*_pfnAllocHook)(_HOOK_REALLOC, pUserData, nNewSize, nBlockUse, lRequest, (const unsigned char *)szFileName, nLine))
{
if (szFileName)
_RPT2(_CRT_WARN, "Client hook re-allocation failure at file %hs line %d.\n",
szFileName, nLine);
else
_RPT0(_CRT_WARN, "Client hook re-allocation failure.\n");
return NULL;
}
/* Diagnostic memory allocation from this point on */
if (nNewSize > (size_t)(_HEAP_MAXREQ - nNoMansLandSize - sizeof(_CrtMemBlockHeader)))
{
if (szFileName)
{
_RPT3(_CRT_ERROR,
"Invalid allocation size: %Iu bytes.\n" _ALLOCATION_FILE_LINENUM,
nNewSize, szFileName, nLine);
}
else
{
_RPT1(_CRT_ERROR, "Invalid allocation size: %Iu bytes.\n", nNewSize);
}
errno = ENOMEM;
return NULL;
}
if (nBlockUse != _NORMAL_BLOCK
&& _BLOCK_TYPE(nBlockUse) != _CLIENT_BLOCK
&& _BLOCK_TYPE(nBlockUse) != _CRT_BLOCK)
{
if (szFileName)
{
_RPT2(_CRT_ERROR,
"Error: memory allocation: bad memory block type.\n" _ALLOCATION_FILE_LINENUM,
szFileName, nLine);
}
else
{
_RPT0(_CRT_ERROR, "Error: memory allocation: bad memory block type.\n");
}
} else
{
if ( CheckBytes((unsigned char*)((uintptr_t)pUserData & ~(sizeof(uintptr_t) -1)) -nAlignGapSize,_bAlignLandFill, nAlignGapSize))
{
// We don't know (yet) where (file, linenum) pUserData was allocated
_RPT1(_CRT_ERROR, "The Block at 0x%p was allocated by aligned routines, use _aligned_realloc()", pUserData);
errno = EINVAL;
return NULL;
}
}
/*
* If this ASSERT fails, a bad pointer has been passed in. It may be
* totally bogus, or it may have been allocated from another heap.
* The pointer MUST come from the 'local' heap.
*/
_ASSERTE(_CrtIsValidHeapPointer(pUserData));
/* get a pointer to memory block header */
pOldBlock = pHdr(pUserData);
if (pOldBlock->nBlockUse == _IGNORE_BLOCK)
fIgnore = TRUE;
if (fIgnore)
{
_ASSERTE(pOldBlock->nLine == IGNORE_LINE && pOldBlock->lRequest == IGNORE_REQ);
}
else {
/* Error if freeing incorrect memory type */
/* CRT blocks can be treated as NORMAL blocks */
if (_BLOCK_TYPE(pOldBlock->nBlockUse) == _CRT_BLOCK && _BLOCK_TYPE(nBlockUse) == _NORMAL_BLOCK)
nBlockUse = _CRT_BLOCK;
/* The following assertion was prone to false positives - JWM */
/* _ASSERTE(_BLOCK_TYPE(pOldBlock->nBlockUse)==_BLOCK_TYPE(nBlockUse)); */
/* checking the size of previous block */
if (_lTotalAlloc < pOldBlock->nDataSize)
{
_RPT1(_CRT_ERROR, "Error: possible heap corruption at or near 0x%p", pUserData);
errno = EINVAL;
return NULL;
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?