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

📄 isemem.cpp

📁 内存泄漏管理,介绍内存泄漏的避免方法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	if ((pb=(unsigned char *)malloc(size+8)) == 0)
	{
		LeaveCriticalSection(&ise_mbheader_access);
		return (void*)0;
	}

	/* 分配对应的内存信息块 */
	if ((pbm=_create_mb_header()) == 0)
	{
		free(pb);
		LeaveCriticalSection(&ise_mbheader_access);
		return (void*)0;
	}

	/* 填充废料,并设置头、尾标志 */
	memset((void*)pb, (int)ISE_MB_FILL_BYTE, size+8);

	*((unsigned long *)pb) = ISE_MEMBLOCK_MARK;
	*((unsigned long *)(unsigned char *)(pb+4+size)) = ISE_MEMBLOCK_MARK;

	/* 填写内存信息块 */
	pbm->prev	= 0;
	pbm->next	= 0;

	pbm->pbegin = pb;
	pbm->pstart = pb+4;

	pbm->total_len = size+8;
	pbm->use_len   = size;

	pbm->useflag   = 0x1;

	assert(strlen(fn) < ((sizeof(pbm->filename)/sizeof(pbm->filename[0]))-1));
	strcpy(pbm->filename, fn);
	pbm->linenum = (long)linenum;
	
	/* 将信息块插入信息块链表 */
	_insert_mb_header(pbm);	

	LeaveCriticalSection(&ise_mbheader_access);

	return (void*)(unsigned char *)(pbm->pstart);
}


/* 释放一个受防护的内存块 */
ISEMEM_API void CALLAGREEMENT _ise_free(void *p)
{
	unsigned char	*pb = (unsigned char *)p;
	LPISE_MBINFO	pmb = 0;

	assert(p);

	EnterCriticalSection(&ise_mbheader_access);

	/* 查找对应的信息块 */
	pmb = _find_mb_header(p);
	assert(pmb);				/* 如果找不到对应的信息块,则说明程序发生了混乱,内存信息被覆盖 */
	assert(pb == pmb->pstart);	/* 待释放指针必须是内存块用户首地址 */

	/* 从链表中摘除信息块 */
	_moved_mb_header(pmb);		/* 必然会找到此信息块(因为这是由_find_mb_header函数返回的)*/

	/* 向待释放内存块填充废料 */
	memset((void*)pmb->pbegin, (int)ISE_MB_FILL_BYTE, (size_t)pmb->total_len);

	pb = pmb->pbegin;

	/* 释放信息块 */
	_free_mb_header(pmb);
	
	free(pb);

	LeaveCriticalSection(&ise_mbheader_access);
}


/* 重新分配一块受防护的内存块 */
ISEMEM_API void * CALLAGREEMENT _ise_realloc(void **ppv, long newsize, const char *fn, int linenum)
{
	unsigned char	*pb = (unsigned char *)(ppv[0]);
	void			*presult;
	LPISE_MBINFO	pmb = 0;

	assert(newsize);

	if (pb == 0)
	{
		return (ppv[0]=_ise_malloc(newsize, fn, linenum));
	}

	EnterCriticalSection(&ise_mbheader_access);

	/* 查找对应的信息块 */
	pmb = _find_mb_header((void*)pb);
	assert(pmb);				/* 应该可以找到,否则说明程序发生了混乱,内存信息被覆盖 */
	assert(pb == pmb->pstart);	/* 待释放指针必须是内存块用户首地址 */

	if (newsize < pmb->use_len)
	{
		presult = realloc((void*)pmb->pbegin, (size_t)newsize+8);
		assert(presult);		/* 缩小空间不应失败,否则说明系统已不稳定 */
		assert(*((unsigned long *)presult) == ISE_MEMBLOCK_MARK);

		pmb->pbegin    = (unsigned char *)presult;
		pmb->pstart    = pmb->pbegin+4;
		pmb->total_len = newsize+8;
		pmb->use_len   = newsize;
		*(unsigned long *)(unsigned char *)(pmb->pstart+newsize) = ISE_MEMBLOCK_MARK;

		assert(strlen(fn) < ((sizeof(pmb->filename)/sizeof(pmb->filename[0]))-1));
		strcpy(pmb->filename, fn);
		pmb->linenum = (long)linenum;
	}
	else if (newsize == pmb->use_len)
	{
		;						/* 无需重分配 */
	}
	else
	{
		if ((presult=realloc((void*)pmb->pbegin, (size_t)newsize+8)) == 0)
		{
			LeaveCriticalSection(&ise_mbheader_access);
			return (void*)0;	/* 内存不足,返回0,原内存块及对应的信息块继续有效 */
		}
		
		assert(*((unsigned long *)presult) == ISE_MEMBLOCK_MARK);
		
		pmb->pbegin    = (unsigned char *)presult;
		pmb->pstart    = pmb->pbegin+4;

		/* 向新扩展的内存区填充废料 */
		memset((void*)(unsigned char *)(pmb->pstart+pmb->use_len), (int)ISE_MB_FILL_BYTE, (size_t)(newsize-pmb->use_len));

		*(unsigned long *)(unsigned char *)(pmb->pstart+newsize) = ISE_MEMBLOCK_MARK;

		pmb->total_len = newsize+8;
		pmb->use_len   = newsize;
		
		assert(strlen(fn) < ((sizeof(pmb->filename)/sizeof(pmb->filename[0]))-1));
		strcpy(pmb->filename, fn);
		pmb->linenum = (long)linenum;
	}

	LeaveCriticalSection(&ise_mbheader_access);

	return (void*)pmb->pstart;
}


/* 获取当前受防护的内存块的总个数 */
ISEMEM_API int CALLAGREEMENT ise_get_mb_count(void)
{
	unsigned long count = 0;

	EnterCriticalSection(&ise_mbheader_access);

	count = ise_memblock_count;

	LeaveCriticalSection(&ise_mbheader_access);

	return (int)count;
}



/********************************************************************
 * 内存防护系统内部函数
 ********************************************************************/


/* 申请一个新的内存信息块 */
static LPISE_MBINFO CALLAGREEMENT _create_mb_header(void)
{
	LPISE_MBINFO	pmb;

	/* 从私有堆中分配一个新的内存信息块 */
	if ((pmb=(LPISE_MBINFO)_alloc_heap(sizeof(ISE_MBINFO))) == 0)
	{
		return (LPISE_MBINFO)0;
	}

	/* 初始化为0 */
	memset((void*)pmb, 0, sizeof(ISE_MBINFO));

	/* 设定标签值 */
	pmb->tag0 = ISE_MEMBLOCK_MARK;
	pmb->tag1 = ISE_MEMBLOCK_MARK;

	return pmb;
}


/* 释放一个内存信息块 */
static void CALLAGREEMENT _free_mb_header(LPISE_MBINFO pmb)
{
	assert(pmb);
	assert((pmb->tag0 == ISE_MEMBLOCK_MARK)&&(pmb->tag1 == ISE_MEMBLOCK_MARK));
	assert(pmb->useflag&0x1);	/* 断言它被使用过 */

	/* 填入废料 */
	memset((void*)pmb, (int)ISE_MB_FILL_BYTE, sizeof(ISE_MBINFO));

	/* 释放信息块 */
	_free_heap(pmb);
}


/* 插入一个新的内存信息块(此时块内必须已填写了内存信息) */
static void CALLAGREEMENT _insert_mb_header(LPISE_MBINFO pmb)
{
	LPISE_MBINFO	ptmp;
	LPISE_MBINFO	pbk;

	assert(pmb);

	/* 插入链表头部 */
	if (ise_memblock_header == 0)
	{
		assert(ise_memblock_tail == 0);

		pmb->prev = 0;
		pmb->next = 0;

		ise_memblock_header = pmb;
		ise_memblock_tail   = pmb;
	}
	else
	{
		/* 寻找适合的插入位置(链表按内存块地址从大到小排序)*/
		for (ptmp=ise_memblock_header; ptmp != 0; ptmp = ptmp->next)
		{
			pbk = ptmp;

			if (pmb->pbegin > ptmp->pbegin)
			{
				break;
			}
		}

		if (ptmp == 0)							/* 尾部插入 */
		{
			assert(pbk == ise_memblock_tail);
			assert(pbk->next == 0);

			pmb->prev = pbk;
			pmb->next = 0;
			pbk->next = pmb;

			ise_memblock_tail = pmb;
		}
		else if (ptmp == ise_memblock_header)	/* 头部插入 */
		{
			assert(ptmp == ise_memblock_header);
			assert(ptmp->prev == 0);

			pmb->prev = 0;
			pmb->next = ptmp;
			ptmp->prev = pmb;

			ise_memblock_header = pmb;
		}
		else									/* 中间插入 */
		{
			assert(ptmp->prev);

			pmb->prev = ptmp->prev;
			pmb->next = ptmp;
			
			ptmp->prev->next = pmb;
			ptmp->prev = pmb;
		}
	}

	/* 计数值加1 */
	ise_memblock_count++;
}


/* 摘除一个内存信息块 */
static void CALLAGREEMENT _moved_mb_header(LPISE_MBINFO pmb)
{
	int				i, mark = -1;
	LPISE_MBINFO	ptmp;

	assert(pmb);
	
	ptmp = ise_memblock_header;

	/* 在链表中搜索指定的内存信息块(主要是检验该块的合法性) */
	for (i=0; i<(int)ise_memblock_count; i++, ptmp = ptmp->next)
	{
		if (pmb == ptmp)
		{
			if ((ptmp == ise_memblock_header)&&(ptmp == ise_memblock_tail))
			{	/* 只有一个块 */
				assert(ptmp->prev == ptmp->next);

				ise_memblock_tail = ise_memblock_header = 0;
			}
			else if (ptmp == ise_memblock_header)
			{	/* 摘除头块 */
				ptmp->next->prev = 0;
				ise_memblock_header = ptmp->next;
			}
			else if (ptmp == ise_memblock_tail)
			{	/* 摘除尾块 */
				ptmp->prev->next = 0;
				ise_memblock_tail = ptmp->prev;
			}
			else
			{	/* 摘除中间的信息块 */
				assert(ise_memblock_count > 2);
				ptmp->next->prev = ptmp->prev;
				ptmp->prev->next = ptmp->next;
			}
			/* 计数值减1 */
			ise_memblock_count--;

			mark = 0;		/* 摘除成功 */
			break;
		}
	}

	/* mark 值含义:0-表示摘除成功,-1 -表示不存在的信息块 */
	if (mark == -1)
		assert(0);
}


/* 查找指定指针所在的内存信息块(如果未能找到则返回0) */
static LPISE_MBINFO CALLAGREEMENT _find_mb_header(void *ps)
{
	int				i, mark = -1;
	unsigned char	*pb = (unsigned char *)ps;
	LPISE_MBINFO	ptmp;

	assert(ps);

	ptmp = ise_memblock_header;

	for (i=0; i<(int)ise_memblock_count; i++, ptmp = ptmp->next)
	{
		assert(ptmp);

		/* 查找指定的指针所在的内存块 */
		if ((pb >= ptmp->pstart)&&(pb < (ptmp->pstart+ptmp->use_len)))
		{
			mark = 0; break;
		}
	}

	return (mark == 0) ? ptmp : (LPISE_MBINFO)0;
}


#else








#endif /* _DEBUG */

⌨️ 快捷键说明

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