📄 memmanage.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 + -