📄 klheap.c
字号:
返回值:
假如成功,返回TRUE; 否则返回FALSE
功能描述:
检验的指针是否合法
引用:
************************************************/
#define DEBUG_IsPtrValid 1
static BOOL IsPtrValid( LPCVOID lpvUsed, LPBLOCK * lppRet, LPBLOCK * lpxRet )
{
LPBLOCK p, x;
p = (LPBLOCK)((char*)lpvUsed - sizeof(BUSY));
if ( !IS_BUSY(p) )
{ // 无效的指针
WARNMSG( DEBUG_IsPtrValid, ( "error0: invalid ptr(0x%x),(p=0x%x).\r\n" , lpvUsed, p ) );
KL_SetLastError( ERROR_INVALID_PARAMETER );
//goto ret;
return FALSE;
}
x = (LPBLOCK)((char*)p->busy.lpNext-(BUSY_FLAG+ALLOC_FLAG) );
if ( !x || x->busy.lpPrev != p )
{ // 无效的指针
KL_SetLastError( ERROR_INVALID_PARAMETER );
WARNMSG( DEBUG_IsPtrValid, ( "error1: invalid ptr(0x%x), x=0x%x.\r\n" , lpvUsed, x ) );
//goto ret;
return FALSE;
}
if( lppRet )
*lppRet = p;
if( lpxRet )
*lpxRet = x;
return TRUE;
}
/**************************************************
声明:BOOL WINAPI KL_HeapFree( HANDLE hHeap, DWORD dwFlags, void FAR * lpvUsed )
参数:
hHeap - 堆句柄
dwFlags - 功能,可以为以下值:
HEAP_NO_SERIALIZE - 不需要串行化(互斥操作)
lpvUsed - 之前分配的内存地址
返回值:
假如成功,返回TRUE; 否则返回FALSE
功能描述:
释放之前用KL_HeapAlloc 或KL_HeapRealloc返回的一个内存块
引用:
系统API
************************************************/
#define DEBUG_HEAPFREE 0
BOOL WINAPI KL_HeapFree( HANDLE hHeap, DWORD dwFlags, void FAR * lpvUsed )
{
LPBLOCK p, x;
BOOL bRetv = FALSE;
LPHEAP lpHeap = (LPHEAP)hHeap;
ASSERT_NOTIFY( lpvUsed, "Invalid param at _Free:" );
if ( !lpvUsed ) return FALSE;
//进入互斥段
EnterCriticalLock( lpHeap, TRUE );
DEBUGMSG( DEBUG_HEAPALLOC, ( "+++F(0x%x,lock=%d)F+++.\r\n", KL_GetCurrentThreadId(), lpHeap->iLockCount ) );
if( IsPtrValid( lpvUsed, &p, &x ) == FALSE )
{
WARNMSG( DEBUG_HEAPFREE, ( "erro in KL_HeapFree: invalid ptr(0x%x).\r\n" , lpvUsed ) );
goto ret;
}
p->busy.lpNext = x;
x = p->busy.lpNext;
if ( !IS_BUSY(x) )
{ // 如果下一个块也是空闲的,则组合它们
_RemoveFromFree( lpHeap, x );
p->busy.lpNext = x->busy.lpNext;
x->busy.lpNext->busy.lpPrev = p;
}
if ( (x = p->busy.lpPrev) != 0 && !IS_BUSY(x) )
{ // 如果前一个块也是空闲的,则组合它们
_RemoveFromFree( lpHeap, x );
x->busy.lpNext = p->busy.lpNext;
p->busy.lpNext->busy.lpPrev = x;
p = x;
}
//将该块插入堆空闲链表
_InsertToFree( lpHeap, p );
bRetv = TRUE;
ret:
//离开互斥段
DEBUGMSG( DEBUG_HEAPALLOC, ( "---F(0x%x)F---.\r\n", KL_GetCurrentThreadId() ) );
LeaveCriticalLock( lpHeap, TRUE );
return bRetv;
}
/**************************************************
声明:LPVOID WINAPI KL_HeapReAlloc( HANDLE hHeap, DWORD dwFlags, LPVOID lpOldPtr, DWORD nNewAllocSize )
参数:
hHeap - 堆句柄
dwFlags - 功能,可以为以下值:
HEAP_NO_SERIALIZE - 不需要串行化(互斥操作)
lpOldPtr - 之前已经分配的内存。如果是NULL,等同与KL_HeapAlloc
nNewAllocSize - 需要重新分配的内存大小。 如果是0,等同与KL_HeapFree
返回值:
假如成功,返回非NULL的指针; 否则返回NULL,不会改变之前的指针
功能描述:
从堆里重新分配一个内存快
引用:
系统API
************************************************/
#define DEBUG_HEAPREALLOC 0
LPVOID WINAPI KL_HeapReAlloc( HANDLE hHeap, DWORD dwFlags, LPVOID lpOldPtr, DWORD nNewAllocSize )
{
register void *newp = 0;
LPBLOCK p, next, x;
register DWORD oldsz;
LPHEAP lpHeap = (LPHEAP)hHeap;
DWORD dwOldSizeSave = 0;
// 如果是NULL,等同与KL_HeapAlloc
if ( !lpOldPtr )
return KL_HeapAlloc( lpHeap, dwFlags, nNewAllocSize );
// 如果是0,等同与KL_HeapFree
if ( !nNewAllocSize )
{
KL_HeapFree( lpHeap, dwFlags, lpOldPtr );
return 0;
}
// 对齐
nNewAllocSize = (nNewAllocSize + ALIGNMASK) & ~ALIGNMASK;
//进入互斥段
EnterCriticalLock( lpHeap, TRUE );
if( IsPtrValid( lpOldPtr, &p, &next ) == FALSE )
{
WARNMSG( DEBUG_HEAPFREE, ( "erro in KL_HeapReAlloc: invalid ptr(0x%x).\r\n" , lpOldPtr ) );
goto ret;
}
//得到尺寸(不包含头)
dwOldSizeSave = oldsz = (char *)next - (char *)lpOldPtr;
if ( oldsz >= nNewAllocSize )
{
register DWORD sizeleft;
// 新的内存需要小于之前分配的老的内存块,我们只需减少老的内存块
resize:
sizeleft = oldsz - nNewAllocSize; //释放某些bytes
if ( sizeleft > sizeof(BLOCK) )
{ // 将其插入空闲链表
x = (LPBLOCK)((char*)next - sizeleft);
x->busy.lpNext = next;
x->busy.lpPrev = p;
p->busy.lpNext = (LPBLOCK)( (char*)x+(BUSY_FLAG+ALLOC_FLAG) );
next->busy.lpPrev = x;
_InsertToFree( lpHeap, x );
if ( !IS_BUSY(next) )
{ //如果与下一个空闲块的地址是连续,则组合它们
_RemoveFromFree( lpHeap, next );
x->busy.lpNext = next->busy.lpNext;
next->busy.lpNext->busy.lpPrev = x;
}
}
newp = lpOldPtr;
}
else if ( !IS_BUSY(next) && (x=next->busy.lpNext) != 0 &&
(oldsz = (char*)x - (char*)lpOldPtr) >= nNewAllocSize )
{ //下一个块是空闲块并且其大小满足需要的尺寸
_RemoveFromFree( lpHeap, next );
p->busy.lpNext = (LPBLOCK)( (char*)x+(BUSY_FLAG+ALLOC_FLAG) );
x->busy.lpPrev = p;
next = x;
goto resize;
}
else if ( (x=p->busy.lpPrev) != 0 && !IS_BUSY(x) &&
(oldsz = (char*)next - ((char*)x+sizeof(BUSY))) >= nNewAllocSize )
{
char *from, *to;
DWORD n;
//前一个块是空闲块并且其大小满足需要的尺寸
_RemoveFromFree( lpHeap, x );
x->busy.lpNext = (LPBLOCK)( (char*)next + (BUSY_FLAG+ALLOC_FLAG) );
next->busy.lpPrev = x;
from = (char*)p + sizeof(BUSY);
to = (char*)x + sizeof(BUSY);
n = (char *)next - (char *)lpOldPtr;
// 拷贝内容
memmove( to, from, n );
p = x;
lpOldPtr = (char*)p + sizeof(BUSY);
goto resize;
}
else
{
// 需要一个完全新的块
LeaveCriticalLock( lpHeap, TRUE );//LN:2003-05-13, Add
// 重新分配
if ( !(newp = KL_HeapAlloc( lpHeap, dwFlags, nNewAllocSize ) ) ) //;Mem_Alloc( nNewAllocSize )) )
return 0;
// 拷贝内容
memmove( newp, lpOldPtr, (char *)next - (char *)lpOldPtr );
// 释放老的
KL_HeapFree( lpHeap, dwFlags, lpOldPtr );
return newp;
}
ret:
//离开互斥段
LeaveCriticalLock( lpHeap, TRUE );
if( dwOldSizeSave < nNewAllocSize && (dwFlags & HEAP_ZERO_MEMORY ) )
{ // 将多于的内存内容清为0
memset( (char*)newp + dwOldSizeSave, 0, nNewAllocSize - dwOldSizeSave );
}
return newp;
}
/**************************************************
声明:int Heap_Enum( LPHEAP lpHeap, LPHEAPENUMPROC lpfn, LPARAM lParam, UINT uiFlag )
参数:
lpHeap - HEAP结构指针
lpfn - 枚举功能
lParam - 传递给枚举功能的参数
uiFlag - 保留
返回值:
假如成功,返回TRUE; 否则返回FALSE
功能描述:
枚举所有已分配的块
引用:
************************************************/
static int Heap_Enum( LPHEAP lpHeap, LPHEAPENUMPROC lpfn, LPARAM lParam, UINT uiFlag )
{
LPBLOCK lpBlock, lpFirstBlock;
EnterCriticalLock( lpHeap, TRUE );
lpFirstBlock = lpBlock = lpHeap->lpFirstBlock;
while( lpBlock )
{
if( IS_ALLOC(lpBlock) )
{
if( lpfn( ((LPBYTE)lpBlock) + sizeof( BUSY ), lParam ) == 0 )
break; // not contunue
}
lpBlock = lpBlock->busy.lpNext;
lpBlock = (LPBLOCK) ( (DWORD)lpBlock & ( ~(ALLOC_FLAG+BUSY_FLAG) ) );
}
LeaveCriticalLock( lpHeap, TRUE );
return TRUE;
}
/**************************************************
声明:BOOL WINAPI KL_HeapValidate( HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem )
参数:
hHeap -堆句柄(调用HeapCreate返回的句柄)
dwFlags – 属性,可以是:
HEAP_NO_SERIALIZE – 说明当进行堆操作时不必进行互斥
lpMem – 保留,必须为NULL
返回值:
假如成功,返回TRUE; 否则返回FALSE
功能描述:
检查堆是否有效
引用:
系统API
************************************************/
#define IS_ZERO_PTR( p ) ( ( (DWORD)p ) < 0x10000 )
BOOL WINAPI KL_HeapValidate( HANDLE hHeap,
DWORD dwFlags,
LPCVOID lpMem )
{
LPHEAP lpHeap = (LPHEAP)hHeap;
LPBLOCK p, lpPrev;
int iRetv = 1;
if( lpHeap )
{
EnterCriticalLock( lpHeap, !(dwFlags & HEAP_NO_SERIALIZE) );
if( lpMem )
{
iRetv = IsPtrValid( lpMem, NULL, NULL );
}
else
{
lpPrev = NULL;
for ( p = lpHeap->lpFreeList; p; p = p->lpNextFree )
{
if( IS_ZERO_PTR( p ) )
{
ERRORMSG( 1, ("Invalidate heap freelist ptr:lpHeap=%x,p=0x%x.\r\n", lpHeap, p ) );
iRetv = 0;
break;
}
else if( p->lpPrevFree != lpPrev )
{
ERRORMSG( 1, ("Invalidate heap freelist ptr:lpHeap=%x,p=0x%x,p->lpPrevFree=%x,lpPrev=%x.\r\n", lpHeap, p , p->lpPrevFree, lpPrev ) );
iRetv = 0;
break;
}
lpPrev = p;
}
lpPrev = NULL;
for ( p = lpHeap->lpFirstBlock; p; p = (LPBLOCK)( (DWORD)p->busy.lpNext & (~(BUSY_FLAG+ALLOC_FLAG) ) ) )
{
if( IS_ZERO_PTR( p ) )
{
ERRORMSG( 1, ("Invalidate heap freelist ptr:lpHeap=%x,0xp=0x%x.\r\n", lpHeap, p ) );
iRetv = 0;
break;
}
else if( p->busy.lpPrev != lpPrev )
{
ERRORMSG( 1, ("Invalidate heap busy list, lpHeap=%x,p=0x%x.\r\n", lpHeap, p ) );
iRetv = 0;
break;
}
lpPrev = p;
}
}
LeaveCriticalLock( lpHeap, !(dwFlags & HEAP_NO_SERIALIZE) );
}
return iRetv;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -