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

📄 vfxmemory.cpp

📁 DirectInput的基本实现 只是基本应用
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// vfxmemory.cpp
// 
// VictoryCore Code
// memory allocer
//
// Author : lanzhengpeng(兰征鹏)
// More author :
// Create time : 2002-6-13
// Modify time :
// 内存分配代码依赖一个全局变量。此全局变量析构的时候,CRT可能已经被(部分)销毁
// 导致在析构函数中不能使用CRT的相关函数。而在最后又需要报告内存信息,需
// 要使用到C运行库的_vsnprintf函数。
// 妥协的做法是在析构函数里不做任何事,而在DLL_PROCESS_DETACH时报告内存信息。
// 事实上的内存分配和错误报告输出相互依赖也导致问题,故错误输出也需要单独写
//-----------------------------------------------------------------------------
#include "stdafx.h"
#ifdef _MFC
	#include <afx.h>
#else
	#include <windows.h>
#endif
#include "vfxmemory.h"
#include <cassert>
#include <new>
#include <stdio.h>

#if defined(_MSC_VER) && _MSC_VER >= 1300
#	define USE_STD	std
#else
#	define USE_STD
#endif

#undef vT
#define vT(x)	x

static void __cdecl __MemoryTrace(const char * lpszFormat, ...)
{
#ifdef VFX_DEBUG_MEMORY
	va_list pArgs;
	va_start(pArgs,lpszFormat);

	char Tmp[1024];
	int nBuf = _vsntprintf(Tmp,1024,lpszFormat,pArgs);
	::OutputDebugStringA(Tmp);

	va_end(pArgs);
#endif
}

namespace VFX_Memory
{

#ifdef _MT
static long g_memory_critical = 0;
void memory_lock()
{
	if(InterlockedExchange(&g_memory_critical,1))
		while(InterlockedExchange(&g_memory_critical,1)) Sleep(0);
}
void memory_unlock()
{
	InterlockedExchange(&g_memory_critical,0);
}
class auto_memory_lock
{
public:
	auto_memory_lock()
	{ memory_lock();}
	~auto_memory_lock()
	{ memory_unlock();}
};
#endif //end _MT

#ifdef VFX_DEBUG_MEMORY
const unsigned int	c_uMalloc0xCC	= 0xCCCCCCCC;
static size_t g_alloc_times = 0;
static __int64 g_alloc_break_times = -1;
static size_t g_memory_obj = 0;
static size_t g_memoey_used = 0;
static size_t g_memory_max = 0;

static int _vfxMemoryOutputReport();
#endif	//end VFX_DEBUG_MEMORY

small_alloc	*	small_alloc::__psmall_alloc = 0;

small_alloc::small_alloc()
{
	memset(pool_chunk,0,sizeof(pool_chunk));
}

small_alloc::~small_alloc()
{
	destructor();
}

void small_alloc::destructor()
{
#ifdef VFX_DEBUG_MEMORY
	_vfxMemoryOutputReport();
	Dump();

	size_t size = poolArray.GetNumber();
	_small_cookie **	p = poolArray.GetData();
	
	for(size_t i=0;i<size;++i,++p)
		__free(*p);
#endif	//end VFX_DEBUG_MEMORY
}

_small_cookie * small_alloc::alloc_pool(size_t size)
{
	size = round_up(size);
	size_t newsize = round_up(size + sizeof(_small_cookie) - sizeof(_small_cookie *)) + sizeof(unsigned);
	_small_cookie * p = reinterpret_cast<_small_cookie *>(__alloc(newsize * __pool_size));

	{
		_small_cookie * pp = reinterpret_cast<_small_cookie*>(p);
		_small_cookie * next;
		for (size_t i=0;i<__pool_size-1;++i,pp=next)
		{
			next = reinterpret_cast<_small_cookie*>((INT_PTR)pp + newsize);
			pp->next = next;
			pp->size = size;
#ifdef VFX_DEBUG_MEMORY
			pp->file = 0;
			pp->line = 0;
			pp->id = (unsigned int)-1;
#endif	//end VFX_DEBUG_MEMORY
		}
		pp->next = 0;
		pp->size = size;
#ifdef VFX_DEBUG_MEMORY
			pp->file = 0;
			pp->line = 0;
			pp->id = (unsigned int)-1;
#endif	//end VFX_DEBUG_MEMORY
	}

	poolArray.Add(p);
#ifdef VFX_DEBUG_MEMORY
	sizeArray.Add(size);
#endif	//end VFX_DEBUG_MEMORY
	return p;
}

#ifdef VFX_DEBUG_MEMORY
void * small_alloc::alloc(size_t size,const char * file,unsigned int line)
{
	assert(size <= __max_bytes);

	if(size <= 0) size = 1;
	_small_cookie * &free_list = pool_chunk[(size - 1) / __align_size];
	if(free_list == 0)
		free_list = alloc_pool(size);
	void * ret = free_list->data;
	free_list->file = file;
	free_list->line = line;
	free_list->size = size;
	free_list->id = g_alloc_times++;
	free_list->dccc = c_uMalloc0xCC;
	g_memoey_used += free_list->size;
	g_memory_obj++;
	if(g_memory_max < g_memoey_used)
		g_memory_max = g_memoey_used;
	free_list = free_list->next;

	*(unsigned *)((INT_PTR)ret + size) = c_uMalloc0xCC;
	return ret;
}

void small_alloc::free(void * memory,const char * file,unsigned int line)
{
	_small_cookie * pcook = reinterpret_cast<_small_cookie *>
		((INT_PTR)memory - sizeof(_small_cookie) + sizeof(_small_cookie *));
	size_t size = pcook->size;
	assert(size <= __max_bytes);

	if(pcook->dccc != c_uMalloc0xCC)//前效验位有问题,很可能越界或错误的指针
	{
		if(file)
			__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!!!\n"),file,line,memory);
		if(IsBadReadPtr(pcook->file,4) == 0)
			__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!!! Alloc ID : %d\n"),pcook->file,pcook->line,memory,pcook->id);
		else
			__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x) failed!!! Alloc ID : %d\n"),memory,pcook->id);
	}
	UINT_PTR * pdccc = reinterpret_cast<unsigned*>((INT_PTR)memory + size);
	if(*pdccc != c_uMalloc0xCC)//后效验位有问题,很可能越界或错误的指针
	{
		if(file)
			__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!\n"),file,line,memory);
		if(IsBadReadPtr(pcook->file,4) == 0)
			__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed! Alloc ID : %d\n"),pcook->file,pcook->line,memory,pcook->id);
		else
			__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x) failed! Alloc ID : %d\n"),memory,pcook->id);
	}

	memset(memory,0xCC,size);

	g_memory_obj--;
	g_memoey_used -= size;
	
	_small_cookie * & free_list = pool_chunk[(pcook->size - 1) / __align_size];
	pcook->next = free_list;
	free_list = pcook;
	pcook->id = (unsigned int)-1;
}

#else
void * small_alloc::alloc(size_t size)
{
	if(size <= 0) size = 1;
	_small_cookie * &free_list = pool_chunk[(size - 1) / __align_size];
	if(free_list == 0)
		free_list = alloc_pool(size);
	free_list->size = size;
	void * ret = free_list->data;
	free_list = free_list->next;

	return ret;
}

void small_alloc::free(void * memory)
{
	_small_cookie * pcook = reinterpret_cast<_small_cookie *>
		((INT_PTR)memory - sizeof(_small_cookie) + sizeof(_small_cookie *));
	_small_cookie * & free_list = pool_chunk[(pcook->size - 1) / __align_size];
	pcook->next = free_list;
	free_list = pcook;
}
#endif	//end VFX_DEBUG_MEMORY

#ifdef VFX_DEBUG_MEMORY
void small_alloc::dump_memory(_small_cookie * check,size_t leak_size)
{
	assert(leak_size > 0);

	size_t size = round_up(leak_size + sizeof(_small_cookie) - sizeof(_small_cookie *)) + sizeof(unsigned);
	for(register int i = 0 ; i < __pool_size ; ++i)
	{
		if (check->id != (unsigned int)-1)
		{
			if(check->file && IsBadReadPtr(check->file,4) == 0)
				__MemoryTrace(vT("%s(%d) : Memory leak! There have %d bytes memory had not be delete. Alloc ID : %d\n")
				,check->file,check->line,leak_size,check->id);
			else
				__MemoryTrace(vT("Unkown position : Memory leak! There have %d bytes memory had not be delete. Alloc ID : %d\n")
				,leak_size,check->id);
		}
		check = reinterpret_cast<_small_cookie*>((INT_PTR)check + size);
	}
}

void small_alloc::Dump()
{
	for(unsigned int i = 0; i < poolArray.GetNumber(); ++i)
		dump_memory(poolArray[i],sizeArray[i]);
}
void small_alloc::Check()
{
	for(size_t n=0; n<poolArray.GetNumber(); ++n)
	{
		size_t size = sizeArray[n];
		size_t newsize = round_up(size + sizeof(_small_cookie) - sizeof(_small_cookie *)) + sizeof(unsigned);
		_small_cookie * pcook = poolArray[n];

		for(int i=0; i<__pool_size; ++i)
		{
			//前效验位有问题,很可能越界或错误的指针
			if(pcook->dccc != c_uMalloc0xCC && pcook->id != (unsigned int)-1)
			{
				if(IsBadReadPtr(pcook->file,4) == 0)
					__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed!!! Alloc ID : %d\n"),
								pcook->file,pcook->line,pcook->data,pcook->id);
				else
					__MemoryTrace(vT("Unkown position : Verify pointer(0x%8.8x) failed!!! Alloc ID : %d\n"),
								pcook->data,pcook->id);
			}
			unsigned int * pdccc = reinterpret_cast<unsigned int*>(((INT_PTR)pcook->data) + pcook->size);
			//后效验位有问题,很可能越界或错误的指针
			if(*pdccc != c_uMalloc0xCC && pcook->id != (unsigned int)-1)
			{
				if(IsBadReadPtr(pcook->file,4) == 0)
					__MemoryTrace(vT("%s(%d) : Verify pointer(0x%8.8x) failed! Alloc ID : %d\n"),

⌨️ 快捷键说明

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