mmgr.cpp

来自「ftgl-2.1.2 夸平台的opengl显示字体」· C++ 代码 · 共 1,668 行 · 第 1/5 页

CPP
1,668
字号
// ---------------------------------------------------------------------------------------------------------------------------------static	const char	*ownerString(const char *sourceFile, const unsigned int sourceLine, const char *sourceFunc){	static	char	str[90];	memset(str, 0, sizeof(str));	sprintf(str, "%s(%05d)::%s", sourceFileStripper(sourceFile), sourceLine, sourceFunc);	return str;}// ---------------------------------------------------------------------------------------------------------------------------------static	const char	*insertCommas(unsigned int value){	static	char	str[30];	memset(str, 0, sizeof(str));	sprintf(str, "%u", value);	if (strlen(str) > 3)	{		memmove(&str[strlen(str)-3], &str[strlen(str)-4], 4);		str[strlen(str) - 4] = ',';	}	if (strlen(str) > 7)	{		memmove(&str[strlen(str)-7], &str[strlen(str)-8], 8);		str[strlen(str) - 8] = ',';	}	if (strlen(str) > 11)	{		memmove(&str[strlen(str)-11], &str[strlen(str)-12], 12);		str[strlen(str) - 12] = ',';	}	return str;}// ---------------------------------------------------------------------------------------------------------------------------------static	const char	*memorySizeString(unsigned long size){	static	char	str[90];	     if (size > (1024*1024))	sprintf(str, "%10s (%7.2fM)", insertCommas(size), (float) size / (1024.0f * 1024.0f));	else if (size > 1024)		sprintf(str, "%10s (%7.2fK)", insertCommas(size), (float) size / 1024.0f);	else				sprintf(str, "%10s bytes     ", insertCommas(size));	return str;}// ---------------------------------------------------------------------------------------------------------------------------------static	sAllocUnit	*findAllocUnit(const void *reportedAddress){	// Just in case...	m_assert(reportedAddress != NULL);	// Use the address to locate the hash index. Note that we shift off the lower four bits. This is because most allocated	// addresses will be on four-, eight- or even sixteen-byte boundaries. If we didn't do this, the hash index would not have	// very good coverage.	unsigned int	hashIndex = ((unsigned int) reportedAddress >> 4) & (hashSize - 1);	sAllocUnit	*ptr = hashTable[hashIndex];	while(ptr)	{		if (ptr->reportedAddress == reportedAddress) return ptr;		ptr = ptr->next;	}	return NULL;}// ---------------------------------------------------------------------------------------------------------------------------------static	size_t	calculateActualSize(const size_t reportedSize){	// We use DWORDS as our padding, and a long is guaranteed to be 4 bytes, but an int is not (ANSI defines an int as	// being the standard word size for a processor; on a 32-bit machine, that's 4 bytes, but on a 64-bit machine, it's	// 8 bytes, which means an int can actually be larger than a long.)	return reportedSize + paddingSize * sizeof(long) * 2;}// ---------------------------------------------------------------------------------------------------------------------------------static	size_t	calculateReportedSize(const size_t actualSize){	// We use DWORDS as our padding, and a long is guaranteed to be 4 bytes, but an int is not (ANSI defines an int as	// being the standard word size for a processor; on a 32-bit machine, that's 4 bytes, but on a 64-bit machine, it's	// 8 bytes, which means an int can actually be larger than a long.)	return actualSize - paddingSize * sizeof(long) * 2;}// ---------------------------------------------------------------------------------------------------------------------------------static	void	*calculateReportedAddress(const void *actualAddress){	// We allow this...	if (!actualAddress) return NULL;	// JUst account for the padding	return (void *) ((char *) actualAddress + sizeof(long) * paddingSize);}// ---------------------------------------------------------------------------------------------------------------------------------static	void	wipeWithPattern(sAllocUnit *allocUnit, unsigned long pattern, const unsigned int originalReportedSize = 0){	// For a serious test run, we use wipes of random a random value. However, if this causes a crash, we don't want it to	// crash in a differnt place each time, so we specifically DO NOT call srand. If, by chance your program calls srand(),	// you may wish to disable that when running with a random wipe test. This will make any crashes more consistent so they	// can be tracked down easier.	if (randomWipe)	{		pattern = ((rand() & 0xff) << 24) | ((rand() & 0xff) << 16) | ((rand() & 0xff) << 8) | (rand() & 0xff);	}	// -DOC- We should wipe with 0's if we're not in debug mode, so we can help hide bugs if possible when we release the	// product. So uncomment the following line for releases.	//	// Note that the "alwaysWipeAll" should be turned on for this to have effect, otherwise it won't do much good. But we'll	// leave it this way (as an option) because this does slow things down.//	pattern = 0;	// This part of the operation is optional	if (alwaysWipeAll && allocUnit->reportedSize > originalReportedSize)	{		// Fill the bulk		long	*lptr = (long *) ((char *)allocUnit->reportedAddress + originalReportedSize);		int	length = allocUnit->reportedSize - originalReportedSize;		int	i;		for (i = 0; i < (length >> 2); i++, lptr++)		{			*lptr = pattern;		}		// Fill the remainder		unsigned int	shiftCount = 0;		char		*cptr = (char *) lptr;		for (i = 0; i < (length & 0x3); i++, cptr++, shiftCount += 8)		{			*cptr = (pattern & (0xff << shiftCount)) >> shiftCount;		}	}	// Write in the prefix/postfix bytes	long		*pre = (long *) allocUnit->actualAddress;	long		*post = (long *) ((char *)allocUnit->actualAddress + allocUnit->actualSize - paddingSize * sizeof(long));	for (unsigned int i = 0; i < paddingSize; i++, pre++, post++)	{		*pre = prefixPattern;		*post = postfixPattern;	}}// ---------------------------------------------------------------------------------------------------------------------------------static	void	dumpAllocations(FILE *fp){	fprintf(fp, "Alloc.   Addr       Size       Addr       Size                        BreakOn BreakOn              \r\n");	fprintf(fp, "Number Reported   Reported    Actual     Actual     Unused    Method  Dealloc Realloc Allocated by \r\n");	fprintf(fp, "------ ---------- ---------- ---------- ---------- ---------- -------- ------- ------- --------------------------------------------------- \r\n");	for (unsigned int i = 0; i < hashSize; i++)	{		sAllocUnit *ptr = hashTable[i];		while(ptr)		{			fprintf(fp, "%06d 0x%08X 0x%08X 0x%08X 0x%08X 0x%08X %-8s    %c       %c    %s\r\n",				ptr->allocationNumber,				(unsigned int) ptr->reportedAddress, ptr->reportedSize,				(unsigned int) ptr->actualAddress, ptr->actualSize,				m_calcUnused(ptr),				allocationTypes[ptr->allocationType],				ptr->breakOnDealloc ? 'Y':'N',				ptr->breakOnRealloc ? 'Y':'N',				ownerString(ptr->sourceFile, ptr->sourceLine, ptr->sourceFunc));			ptr = ptr->next;		}	}}// ---------------------------------------------------------------------------------------------------------------------------------static	void	dumpLeakReport(){	// Open the report file	FILE	*fp = fopen(memoryLeakLogFile, "w+b");	// If you hit this assert, then the memory report generator is unable to log information to a file (can't open the file for	// some reason.)	m_assert(fp);	if (!fp) return;	// Any leaks?	// Header	static  char    timeString[25];	memset(timeString, 0, sizeof(timeString));	time_t  t = time(NULL);	struct  tm *tme = localtime(&t);	fprintf(fp, " ---------------------------------------------------------------------------------------------------------------------------------- \r\n");	fprintf(fp, "|                                          Memory leak report for:  %02d/%02d/%04d %02d:%02d:%02d                                            |\r\n", tme->tm_mon + 1, tme->tm_mday, tme->tm_year + 1900, tme->tm_hour, tme->tm_min, tme->tm_sec);	fprintf(fp, " ---------------------------------------------------------------------------------------------------------------------------------- \r\n");	fprintf(fp, "\r\n");	fprintf(fp, "\r\n");	if (stats.totalAllocUnitCount)	{		fprintf(fp, "%d memory leak%s found:\r\n", stats.totalAllocUnitCount, stats.totalAllocUnitCount == 1 ? "":"s");	}	else	{		fprintf(fp, "Congratulations! No memory leaks found!\r\n");		// We can finally free up our own memory allocations		if (reservoirBuffer)		{			for (unsigned int i = 0; i < reservoirBufferSize; i++)			{				free(reservoirBuffer[i]);			}			free(reservoirBuffer);			reservoirBuffer = 0;			reservoirBufferSize = 0;			reservoir = NULL;		}	}	fprintf(fp, "\r\n");	if (stats.totalAllocUnitCount)	{		dumpAllocations(fp);	}	fclose(fp);}// ---------------------------------------------------------------------------------------------------------------------------------// We use a static class to let us know when we're in the midst of static deinitialization// ---------------------------------------------------------------------------------------------------------------------------------class	MemStaticTimeTracker{public:	MemStaticTimeTracker() {doCleanupLogOnFirstRun();}	~MemStaticTimeTracker() {staticDeinitTime = true; dumpLeakReport();}};static	MemStaticTimeTracker	mstt;// ---------------------------------------------------------------------------------------------------------------------------------// -DOC- Flags & options -- Call these routines to enable/disable the following options// ---------------------------------------------------------------------------------------------------------------------------------bool	&m_alwaysValidateAll(){	// Force a validation of all allocation units each time we enter this software	return alwaysValidateAll;}// ---------------------------------------------------------------------------------------------------------------------------------bool	&m_alwaysLogAll(){	// Force a log of every allocation & deallocation into memory.log	return alwaysLogAll;}// ---------------------------------------------------------------------------------------------------------------------------------bool	&m_alwaysWipeAll(){	// Force this software to always wipe memory with a pattern when it is being allocated/dallocated	return alwaysWipeAll;}// ---------------------------------------------------------------------------------------------------------------------------------bool	&m_randomeWipe(){	// Force this software to use a random pattern when wiping memory -- good for stress testing	return randomWipe;}// ---------------------------------------------------------------------------------------------------------------------------------// -DOC- Simply call this routine with the address of an allocated block of RAM, to cause it to force a breakpoint when it is// reallocated.// ---------------------------------------------------------------------------------------------------------------------------------bool	&m_breakOnRealloc(void *reportedAddress){	// Locate the existing allocation unit	sAllocUnit	*au = findAllocUnit(reportedAddress);	// If you hit this assert, you tried to set a breakpoint on reallocation for an address that doesn't exist. Interrogate the	// stack frame or the variable 'au' to see which allocation this is.	m_assert(au != NULL);	// If you hit this assert, you tried to set a breakpoint on reallocation for an address that wasn't allocated in a way that	// is compatible with reallocation.	m_assert(au->allocationType == m_alloc_malloc ||		 au->allocationType == m_alloc_calloc ||		 au->allocationType == m_alloc_realloc);	return au->breakOnRealloc;}// ---------------------------------------------------------------------------------------------------------------------------------// -DOC- Simply call this routine with the address of an allocated block of RAM, to cause it to force a breakpoint when it is// deallocated.// ---------------------------------------------------------------------------------------------------------------------------------bool	&m_breakOnDealloc(void *reportedAddress){	// Locate the existing allocation unit	sAllocUnit	*au = findAllocUnit(reportedAddress);	// If you hit this assert, you tried to set a breakpoint on deallocation for an address that doesn't exist. Interrogate the	// stack frame or the variable 'au' to see which allocation this is.	m_assert(au != NULL);	return au->breakOnDealloc;}

⌨️ 快捷键说明

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