C實現的內存chunk管理器

功能:


1.C實現的簡單的,可擴展的內存chunk管理器;

2.支持Top, Push, Pop幾種簡單的操作;

3.由於一個內存chunk可以有多個元素,不同的chunk可以大小不等;


優點:


1.可以將其擴展爲一個簡單的內存管理器,實現分配和釋放的cache機制;

2.可以將其作爲雙向隊列的內部的容器類;

3.用這個chunk存儲大量的簡單對象(支持FIFO)效率遠比用雙向鏈表高(速度),同時更節約內存(雙向鏈表一個node,需要兩個指針維護);


代碼如下,compile and test in visual studio 2005:

#ifndef _CHUNK_LIST_H_
#define _CHUNK_LIST_H_

#define INIT_ELEM_COUNT 20

typedef struct tagChunk
{
	size_t cur;
	size_t end;
	tagChunk*  next;
	tagChunk*  prev;

	char   buf[0];

}Chunk, *pChunk;


void  InitChunk( pChunk* newChk, size_t elemSize, size_t elemCount )
{
	pChunk chk = *newChk;
	chk = (pChunk)malloc(elemCount * elemSize + sizeof(Chunk));
	if( chk )
	{
		chk->cur = 0;
		chk->end = elemSize * elemCount;
		chk->next = 0;
		chk->prev = 0;

		*newChk = chk;
	}


}

void* Push( pChunk* chk, size_t elemSize )
{
	pChunk curChk = *chk;
	if( curChk->cur + elemSize > curChk->end )
	{
		InitChunk( &curChk->next, elemSize, INIT_ELEM_COUNT);

		*chk = curChk->next;
		if( curChk )
		{
			(*chk)->prev = curChk;
		}

		curChk = *chk;
	}
  
	size_t loc = curChk->cur;
	curChk->cur += elemSize;

	return curChk->buf + loc;
}


void Pop( pChunk* chk, size_t elemSize )
{
	pChunk curChk = *chk;
	if( ( curChk->cur - elemSize ) < 0 )
	{
		if( curChk->prev )
		{
			*chk = curChk->prev;
			free( curChk );
			curChk = *chk;
		}
		else
		{
			return;
		}
	}

	curChk->cur -= elemSize;
}

void* Top( pChunk* chk, size_t elemSize )
{
	pChunk curChk = *chk;
	if( (int)( curChk->cur - elemSize ) < 0 )
	{
		if( curChk->prev )
		{
			*chk = curChk->prev;
			curChk = *chk;
		}
		else
		{
			return NULL;
		}
	}

	return curChk->buf + curChk->cur - elemSize;
}

void UnInit( pChunk chk )
{
	if( chk )
	{
		pChunk head = chk->prev;
		pChunk tail = chk->next;

		while( head )
		{
			pChunk prev = head->prev;
			free( head );
			head = prev;
		}

		while( tail )
		{
			pChunk next = tail->next;
			free( tail );
			tail = next;
		}

		free( chk );
	}
}

pChunk GetHead( pChunk chk )
{
	if( !chk )
		return 0;

	pChunk cur = chk;
	while( cur->prev )
	{
		cur = cur->prev;
	}

	return cur;
}

pChunk GetTail( pChunk chk )
{
	if( !chk )
		return 0;

	pChunk cur = chk;
	while( cur->next )
	{
		cur = cur->next;
	}

	return cur;
}

size_t GetChunkCount( pChunk chk )
{
	if( !chk )
		return 0;

	pChunk head = GetHead( chk );
	size_t count = 0;
	while( head )
	{
		count++;
		head = head->next;
	}

	return count;

}


void TestChunk()
{
	const int itemLen = 400;
	int item[itemLen];
	for( int i = 0; i < itemLen; i++ )
		item[i] = i;

	pChunk chk = 0;
	InitChunk( &chk, sizeof(int),  INIT_ELEM_COUNT );

	for( int i = 0; i < itemLen; i++ )
	{
		*(int*)Push( &chk, sizeof(int) ) = item[i];
	}

	for( int i = 0; i < itemLen; i++ )
	{
		assert( *(int*)Top( &chk, sizeof(int) )  == item[itemLen - 1 - i]);
		Pop( &chk, sizeof(int) );
	}

	( GetChunkCount( chk ) == itemLen / INIT_ELEM_COUNT );

	UnInit( chk );


}





#endif 




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章