📄 dbgheap.c
字号:
/*
* note that all header values will remain valid
* and min(nNewSize,nOldSize) bytes of data will also remain valid
*/
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
RTCCALLBACK(_RTC_FuncCheckSet_hook,(0));
if (fRealloc)
{
if (NULL == (pNewBlock = (_CrtMemBlockHeader *)_realloc_base(pOldBlock,
sizeof(_CrtMemBlockHeader) + nNewSize + nNoMansLandSize)))
{
RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));
return NULL;
}
}
else {
if (NULL == (pNewBlock = (_CrtMemBlockHeader *)_expand_base(pOldBlock,
sizeof(_CrtMemBlockHeader) + nNewSize + nNoMansLandSize)))
{
RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));
return NULL;
}
#ifdef _WIN64
/* _WIN64, because of the LFH, doesn't try to resize if the
block is shrinking. It just returns the original block.
Make sure our own header tracks that properly. */
nNewSize = *pnNewSize = (size_t)HeapSize(_crtheap, 0, pNewBlock)
- sizeof(_CrtMemBlockHeader) - nNoMansLandSize;
#endif /* _WIN64 */
}
/* realloc_base() or expand_base() should keep the same memory content */
__analysis_assume(pNewBlock->nDataSize == pOldBlock->nDataSize);
/* commit allocation */
++_lRequestCurr;
if (!fIgnore)
{
/* keep track of total amount of memory allocated */
if (_lTotalAlloc < SIZE_MAX)
{
_lTotalAlloc -= pNewBlock->nDataSize;
if (SIZE_MAX - _lTotalAlloc > nNewSize)
{
_lTotalAlloc += nNewSize;
}
else
{
_lTotalAlloc = SIZE_MAX;
}
}
_lCurAlloc -= pNewBlock->nDataSize;
_lCurAlloc += nNewSize;
if (_lCurAlloc > _lMaxAlloc)
_lMaxAlloc = _lCurAlloc;
}
// Free this thing from RTC - it will be reallocated a bit later (inside realloc_dbg/expand_dbg)
RTCCALLBACK(_RTC_Free_hook, (pNewBlock, 0));
pUserBlock = pbData(pNewBlock);
/* if the block grew, put in special value */
if (nNewSize > pNewBlock->nDataSize)
memset(pUserBlock + pNewBlock->nDataSize, _bCleanLandFill,
nNewSize - pNewBlock->nDataSize);
/* fill in gap after real block */
memset(pUserBlock + nNewSize, _bNoMansLandFill, nNoMansLandSize);
if (!fIgnore)
{
pNewBlock->szFileName = (char *)szFileName;
pNewBlock->nLine = nLine;
pNewBlock->lRequest = lRequest;
}
pNewBlock->nDataSize = nNewSize;
_ASSERTE(fRealloc || (!fRealloc && pNewBlock == pOldBlock));
RTCCALLBACK(_RTC_FuncCheckSet_hook,(1));
/* if block did not move or ignored, we are done */
if (pNewBlock == pOldBlock || fIgnore)
return (void *)pUserBlock;
/* must remove old memory from dbg heap list */
/* note that new block header pointers still valid */
if (pNewBlock->pBlockHeaderNext)
{
pNewBlock->pBlockHeaderNext->pBlockHeaderPrev
= pNewBlock->pBlockHeaderPrev;
}
else
{
_ASSERTE(_pLastBlock == pOldBlock);
_pLastBlock = pNewBlock->pBlockHeaderPrev;
}
if (pNewBlock->pBlockHeaderPrev)
{
pNewBlock->pBlockHeaderPrev->pBlockHeaderNext
= pNewBlock->pBlockHeaderNext;
}
else
{
_ASSERTE(_pFirstBlock == pOldBlock);
_pFirstBlock = pNewBlock->pBlockHeaderNext;
}
/* put new memory into list */
if (_pFirstBlock)
_pFirstBlock->pBlockHeaderPrev = pNewBlock;
else
_pLastBlock = pNewBlock;
pNewBlock->pBlockHeaderNext = _pFirstBlock;
pNewBlock->pBlockHeaderPrev = NULL;
/* link blocks together */
_pFirstBlock = pNewBlock;
return (void *)pUserBlock;
}
/***
*void * _recalloc() - reallocate items in the heap
*
*Purpose:
* Re-allocates and initializes with 0 a block in the heap to nNewSize*count bytes.
* nNewSize may be either greater or less than the original size of the block.
* The re-allocation may result in moving the block as well as changing
* the size. If the block is moved, the contents of the original block
* are copied over.
*
* Re-allocates 'normal' memory block.
*
*Entry:
* void * pUserData - pointer to previously allocated block
* size_t count - count of items
* size_t nNewSize - requested size for the items
*
*Exit:
* Success: Pointer to (user portion of) memory block
* Failure: NULL
*
*Exceptions:
*
*******************************************************************************/
extern "C" _CRTIMP void * __cdecl _recalloc
(
void * memblock,
size_t count,
size_t size
)
{
void * res = _recalloc_dbg(memblock, count, size, _NORMAL_BLOCK, NULL, 0);
return res;
}
/***
*void * _realloc_dbg() - reallocate a block of memory in the heap
* - with info
*
*Purpose:
* Re-allocates a block in the heap to nNewSize bytes. nNewSize may be
* either greater or less than the original size of the block. The
* re-allocation may result in moving the block as well as changing
* the size. If the block is moved, the contents of the original block
* are copied over.
*
* Re-allocates any type of supported memory block.
*
*Entry:
* void * pUserData - pointer previously allocated block
* size_t nNewSize - requested size for the re-allocated block
* 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 _realloc_dbg(
void * pUserData,
size_t nNewSize,
int nBlockUse,
const char * szFileName,
int nLine
)
{
void * pvBlk;
_mlock(_HEAP_LOCK); /* block other threads */
__try {
/* allocate the block
*/
pvBlk = realloc_help(pUserData,
&nNewSize,
nBlockUse,
szFileName,
nLine,
TRUE);
}
__finally {
_munlock(_HEAP_LOCK); /* release other threads */
}
if (pvBlk)
{
RTCCALLBACK(_RTC_Allocate_hook, (pvBlk, nNewSize, 0));
}
return pvBlk;
}
/***
*void * _recalloc_dbg() - reallocate items in the heap with info
*
*Purpose:
* Re-allocates and initializez with 0 a block in the heap to nNewSize*count bytes.
* nNewSize may be either greater or less than the original size of the block.
* The re-allocation may result in moving the block as well as changing
* the size. If the block is moved, the contents of the original block
* are copied over.
*
* Re-allocates any type of supported memory block.
*
*Entry:
* void * pUserData - pointer previously allocated block
* size_t count - count of items
* size_t nNewSize - requested size for the items
* 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 _recalloc_dbg
(
void * memblock,
size_t count,
size_t size,
int nBlockUse,
const char * szFileName,
int nLine
)
{
size_t size_orig = 0, old_size = 0;
void * retp = NULL;
/* ensure that (size * count) does not overflow */
if (count > 0)
{
_VALIDATE_RETURN_NOEXC((_HEAP_MAXREQ / count) >= size, ENOMEM, NULL);
}
size_orig = size * count;
if (memblock != NULL)
{
old_size = _msize((void*)memblock);
}
retp = _realloc_dbg(memblock, size_orig, nBlockUse, szFileName, nLine);
if (retp != NULL && old_size < size_orig)
{
memset ((char*)retp + old_size, 0, size_orig - old_size);
}
return retp;
}
/***
*void * _expand() - expand/contract a block of memory in the heap
*
*Purpose:
* Resizes a block in the heap to newsize bytes. newsize may be either
* greater (expansion) or less (contraction) than the original size of
* the block. The block is NOT moved. In the case of expansion, if the
* block cannot be expanded to newsize bytes, it is expanded as much as
* possible.
*
* Re-allocates 'normal' memory block.
*
*Entry:
* void * pUserData - pointer to block in the heap previously allocated
* by a call to malloc(), realloc() or _expand().
*
* size_t nNewSize - requested size for the resized block
*
*Exit:
* Success: Pointer to the resized memory block (i.e., pUserData)
* Failure: NULL
*
*Uses:
*
*Exceptions:
* If pUserData does not point to a valid allocation block in the heap,
* _expand() will behave unpredictably and probably corrupt the heap.
*
*******************************************************************************/
extern "C" _CRTIMP void * __cdecl _expand(
void * pUserData,
size_t nNewSize
)
{
void *res = _expand_dbg(pUserData, nNewSize, _NORMAL_BLOCK, NULL, 0);
return res;
}
/***
*void * _expand() - expand/contract a block of memory in the heap
*
*Purpose:
* Resizes a block in the heap to newsize bytes. newsize may be either
* greater (expansion) or less (contraction) than the original size of
* the block. The block is NOT moved. In the case of expansion, if the
* block cannot be expanded to newsize bytes, it is expanded as much as
* possible.
*
* Re-allocates any type of supported memory block.
*
*Entry:
* void * pUserData - pointer to block in the heap previously allocated
* by a call to malloc(), realloc() or _expand().
*
* size_t nNewSize - requested size for the resized block
*
*Exit:
* Success: Pointer to the resized memory block (i.e., pUserData)
* Failure: NULL
*
*Uses:
*
*Exceptions:
* If pUserData does not point to a valid allocation block in the heap,
* _expand() will behave unpredictably and probably corrupt the heap.
*
*******************************************************************************/
extern "C" _CRTIMP void * __cdecl _expand_dbg(
void * pUserData,
size_t nNewSize,
int nBlockUse,
const char * szFileName,
int nLine
)
{
void * pvBlk;
/* validation section */
_VALIDATE_RETURN(pUserData != NULL, EINVAL, NULL);
if (nNewSize > (size_t)(_HEAP_MAXREQ - nNoMansLandSize - sizeof(_CrtMemBlockHeader))) {
errno = ENOMEM;
return NULL;
}
_mlock(_HEAP_LOCK); /* block other threads */
__try {
/* allocate the block
*/
pvBlk = realloc_help(pUserData,
&nNewSize,
nBlockUse,
szFileName,
nLine,
FALSE);
}
__finally {
_munlock(_HEAP_LOCK); /* release other threads */
}
if (pvBlk)
{
RTCCALLBACK(_RTC_Allocate_hook, (pUserData, nNewSize, 0));
}
return pvBlk;
}
extern "C" void __cdecl _free_nolock(
void * pUserData
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -