⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memmanage.c

📁 内存管理源码
💻 C
字号:

/*memory alloc manager,2007-9-3*/
#ifndef NULL
#define NULL   (0)
#endif
#ifndef FALSE
#define  FALSE    (0)
#endif
#ifndef TRUE
#define  TRUE     (1)
#endif
#define  MEM_DEBUG	
#define  MEM_ERROR
#define MAX_FILE_NAME_LEN	(20)
typedef struct T_MemMgr_tag
{
	char acfileName[MAX_FILE_NAME_LEN]; /*分配所在源文件名*/
	unsigned int nLineNum;/*分配所在的行号*/
	unsigned int/*size_t*/ nMemSize;/*分配的内存大小*/
	//int nCheckSum;/*链表节点校验和*/
	void * pAddr;
	struct T_MemMgr_tag * pPreNode;
	struct T_MemMgr_tag * pNextNode;
}T_MemMgr;
#define HEAD_LENGTH	(sizeof(T_MemMgr))

#define	FENSE_FRONT_SIZE	4
#define 	FENSE_FRONT_VAL	"AVIT"
#define	FENSE_END_SIZE       4
#define	FENSE_END_VAL        "TAIL"
/*用户定制信息*/
#define	WARN_ON_ZERO_MALLOC /*用户申请零分配空间时警告信息*/
//#define	FILL_ON_MALLOC /*分配时初始化内存块*/
//#define	FILL_ON_MALLOC_VAL   /*分配初始化时的预设值*/
//#define	FILL_ON_FREE /*释放时填充内存块*/
//#define	FILL_ON_FREE_VAL /*释放时填充内存块的预设值*/
#define	VALIDATE_FREE /*free是检查本内存块是否在链表中*/
//#define	CHECK_ALL_MEMORY_ON_FREE /*free时检查链表中的所有内存块*/
typedef int BOOL;
/*全局双向链表*/
T_MemMgr * pstMemHead = NULL;
T_MemMgr * pstCurMemNode = NULL;
static BOOL bUsingSysMalloc =FALSE;
/*内存分配函数*/
void *Fense_Malloc(/*size_t*/unsigned int size,char *file,unsigned long line)
{
	void *ptr = NULL;
	char  * pTmp = NULL;
	char  * pData = NULL;
	T_MemMgr * pstTmpHead = NULL;
	int nTotalMem2Alloc = 0;
	//检查Fense 的运行时开关,如果Fense 被关闭,则调用malloc
	if(TRUE == bUsingSysMalloc)
	//分配并返回
	{
		ptr=malloc(size);
		return ptr;
	}
	//检查是否零分配,如有则提示警告信息后返回0(用户定制选项)
#ifdef WARN_ON_ZERO_MALLOC
	if(0 == size)
	{
		#if MEM_DEBUG
			printf("Wornning! mem size is zero!\n");
		#endif
		return NULL;
	}
#endif
	//分配内存,包括链表节点区域和前/后监测区域
	
	nTotalMem2Alloc = HEAD_LENGTH + FENSE_FRONT_SIZE + size + FENSE_END_SIZE;
#ifdef MEM_DEBUG
	printf("Total mem 2 alloc[%d]\,head[%d],front[%d],size[%d],end[%d]\n",\
	nTotalMem2Alloc,HEAD_LENGTH , FENSE_FRONT_SIZE , size , FENSE_END_SIZE);
#endif

	pTmp =(char *) malloc(nTotalMem2Alloc); 
	if(NULL==pTmp)
		return NULL;
	//初始化链表节点,保存分配内存的信息,包括分配的大小、所在文件名和行号
	pstTmpHead = (T_MemMgr *)pTmp;
	strncpy(pstTmpHead->acfileName,file,MAX_FILE_NAME_LEN);
	pstTmpHead->nLineNum = line;
	pstTmpHead->nMemSize = size;
	//pstTmpHead->pAddr = pTmp;
	//将此节点插入链表st_Head
	if(NULL == pstMemHead)
	{
		pstMemHead = pstTmpHead;
		pstTmpHead->pPreNode = NULL;
		pstTmpHead->pNextNode=NULL;
		pstCurMemNode=pstTmpHead;
	}
	else
	{
		pstCurMemNode->pNextNode = pstTmpHead;
		pstTmpHead->pPreNode = pstCurMemNode;
		pstTmpHead->pNextNode =NULL;
		pstCurMemNode=pstTmpHead;
	}
	//为本节点区域计算校验和
	//pstTmpHead->nCheckSum = 0;
	//用预设值初始化前监测区域
	pData = pTmp;
	pData += HEAD_LENGTH;
	memcpy(pData,FENSE_FRONT_VAL,FENSE_FRONT_SIZE);

	pData +=FENSE_FRONT_SIZE;
	//用预设值填充用户内存区域(用户定制选项)
	
#ifdef FILL_ON_MALLOC
	memset(pData,FILL_ON_MALLOC_VAL,size);
#endif
	//用预设值初始化后监测区域
	pData += size ;
	memcpy(pData,FENSE_END_VAL,FENSE_END_SIZE);
	//返回用户内存区域的起始位置
	ptr= pTmp + ( HEAD_LENGTH + FENSE_FRONT_SIZE );
	pstTmpHead->pAddr = ptr;
#ifdef MEM_DEBUG
	printf("Fense_Malloc! called by file[%s],line[%d],addr[%x],orgAddr[%x]\n",file,line,ptr,pTmp);
#endif

	return ptr;
}
/*内存释放函数*/
void Fense_Free(void *uptr,char *file,unsigned long line)
{
	T_MemMgr * pstTmpNode = NULL;
	void *ptr = NULL;
	char  * pTmp = NULL;
	char  * pcAddr = NULL;
	char	 * pcFront;
	char	 * pcEnd;
	//检查Fense 的运行时开关,如果Fense 初关闭,则调用free 释译并返回
	if(TRUE == bUsingSysMalloc)
	//分配并返回
	{
		free(uptr);
		return ;
	}
#ifdef MEM_DEBUG
	printf("Fense_Free! called by file[%s],line[%d],addr[%x]!\n",file,line,uptr);
#endif

	//检查所有Fense 管理下的动态内存(用户定制选项)
#ifdef CHECK_ALL_MEMORY_ON_FREE
	pstTmpNode = pstMemHead;
	while(NULL!=pstTmpNode)
	{
		pcFront = (char *)pstTmpNode->pAddr - FENSE_FRONT_SIZE;
		pcEnd = (char *)pstTmpNode->pAddr + pstTmpNode->nMemSize;
		if(memcmp(pcFront, FENSE_FRONT_VAL, FENSE_FRONT_SIZE))
		{
			#if MEM_DEBUG
				printf("Error! Memory front overload,file[%s],line[%d],addr[%x]!\n",file,line,pstTmpNode->pAddr);
			#endif

		}
		if(memcmp(pcEnd, FENSE_END_VAL, FENSE_END_SIZE))
		{
			#if MEM_DEBUG
				printf("Error! Memory back overload,file[%s],line[%d],addr[%x]!\n",file,line,pstTmpNode->pAddr);
			#endif

		}
		pstTmpNode = pstTmpNode->pNextNode;
	}
#endif
	/*判断当前内存块是否在链表st_Head 中,如果不在则提示

	警靠信息,退出(用户定制选项)*/
#ifdef VALIDATE_FREE
	pstTmpNode = pstMemHead;
	while(NULL!=pstTmpNode)
	{
		if(pstTmpNode->pAddr == uptr)
		{
#ifdef MEM_DEBUG
			printf("find addr[%x]  in the addr list!\n",uptr);
#endif

			break;
		}
		else
			pstTmpNode = pstTmpNode->pNextNode;
	}
	if(NULL == pstTmpNode)
	{
		#if MEM_ERROR
			printf("Error! uptr[%x] is not in the addr list!\n",uptr);
		#endif

		return;
	}
		
#endif
	//检查当前内存块是否存在越界操作

	pcFront = (char *)pstTmpNode->pAddr - FENSE_FRONT_SIZE;
	pcEnd = (char *)pstTmpNode->pAddr + pstTmpNode->nMemSize;
	if(memcmp(pcFront, FENSE_FRONT_VAL, FENSE_FRONT_SIZE))
	{
		#ifdef MEM_ERROR
			printf("Error! Current Memory front overload,file[%s],line[%d],addr[%x]!\n",file,line,pstTmpNode->pAddr);
		#endif

	}
	if(memcmp(pcEnd, FENSE_END_VAL, FENSE_END_SIZE))
	{
		#ifdef MEM_ERROR
			printf("Error! Current Memory back overload,file[%s],line[%d],addr[%x]!\n",file,line,pstTmpNode->pAddr);
		#endif

	}
	//将当前内存块的相应的链表节点从st_Head 中删除
	if(pstTmpNode == pstMemHead)
	{
		pstMemHead = pstTmpNode->pNextNode;
	}
	else
	{
		pstTmpNode->pPreNode->pNextNode = pstTmpNode->pNextNode;
		if(NULL!=pstTmpNode->pNextNode)
			pstTmpNode->pNextNode->pPreNode = pstTmpNode->pPreNode;
	}
	//重新计算当前节点的前后相邻节点的校验和

	//用预设值填充被释放的内存区(用户定制选项)
#ifdef FILL_ON_FREE_VAL
	memset((char *)uptr, FILL_ON_FREE_VAL, pstTmpNode->nMemSize);
#endif
	//调用free 释放当前的内存块
	pcAddr = (char *) uptr -FENSE_FRONT_SIZE-HEAD_LENGTH;
#ifdef MEM_DEBUG
	printf("Fense_Free,orgAddr[%x]\n",pcAddr);
#endif

	free(pcAddr);
}

void main()
{
	int i;
	char * ptr = NULL;
	for(i=0; i<10;i++)
	{
		ptr= (char *)Fense_Malloc(1024, __FILE__, __LINE__);
		Fense_Free(ptr, __FILE__, __LINE__);
	}
	//ptr = (char *)malloc(1024);
	//Fense_Free(ptr, __FILE__, __LINE__);
}
/*EOF*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -