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

📄 mmgr.cpp

📁 ftgl-2.1.2 夸平台的opengl显示字体
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// ---------------------------------------------------------------------------------------------------------------------------------//                                                      //                                                      //  _ __ ___  _ __ ___   __ _ _ __      ___ _ __  _ __  // | '_ ` _ \| '_ ` _ \ / _` | '__|    / __| '_ \| '_ \ // | | | | | | | | | | | (_| | |    _ | (__| |_) | |_) |// |_| |_| |_|_| |_| |_|\__, |_|   (_) \___| .__/| .__/ //                       __/ |             | |   | |    //                      |___/              |_|   |_|    //// Memory manager & tracking software//// Best viewed with 8-character tabs and (at least) 132 columns//// ---------------------------------------------------------------------------------------------------------------------------------//// Restrictions & freedoms pertaining to usage and redistribution of this software:////  * This software is 100% free//  * If you use this software (in part or in whole) you must credit the author.//  * This software may not be re-distributed (in part or in whole) in a modified//    form without clear documentation on how to obtain a copy of the original work.//  * You may not use this software to directly or indirectly cause harm to others.//  * This software is provided as-is and without warrantee. Use at your own risk.//// For more information, visit HTTP://www.FluidStudios.com//// ---------------------------------------------------------------------------------------------------------------------------------// Originally created on 12/22/2000 by Paul Nettle//// Copyright 2000, Fluid Studios, Inc., all rights reserved.// ---------------------------------------------------------------------------------------------------------------------------------//// !!IMPORTANT!!//// This software is self-documented with periodic comments. Before you start using this software, perform a search for the string// "-DOC-" to locate pertinent information about how to use this software.//// You are also encouraged to read the comment blocks throughout this source file. They will help you understand how this memory// tracking software works, so you can better utilize it within your applications.//// NOTES://// 1. This code purposely uses no external routines that allocate RAM (other than the raw allocation routines, such as malloc). We//    do this because we want this to be as self-contained as possible. As an example, we don't use assert, because when running//    under WIN32, the assert brings up a dialog box, which allocates RAM. Doing this in the middle of an allocation would be bad.//// 2. When trying to override new/delete under MFC (which has its own version of global new/delete) the linker will complain. In//    order to fix this error, use the compiler option: /FORCE, which will force it to build an executable even with linker errors.//    Be sure to check those errors each time you compile, otherwise, you may miss a valid linker error.//// 3. If you see something that looks odd to you or seems like a strange way of going about doing something, then consider that this//    code was carefully thought out. If something looks odd, then just assume I've got a good reason for doing it that way (an//    example is the use of the class MemStaticTimeTracker.)//// 4. With MFC applications, you will need to comment out any occurance of "#define new DEBUG_NEW" from all source files.//// 5. Include file dependencies are _very_important_ for getting the MMGR to integrate nicely into your application. Be careful if//    you're including standard includes from within your own project inclues; that will break this very specific dependency order. //    It should look like this:////		#include <stdio.h>   // Standard includes MUST come first//		#include <stdlib.h>  ////		#include <streamio>  //////		#include "mmgr.h"    // mmgr.h MUST come next////		#include "myfile1.h" // Project includes MUST come last//		#include "myfile2.h" ////		#include "myfile3.h" ////// ---------------------------------------------------------------------------------------------------------------------------------//#include "stdafx.h"#include <iostream>#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <string.h>#include <time.h>#include <stdarg.h>#include <new>
#ifndef	WIN32#include <unistd.h>#endif#include "mmgr.h"// ---------------------------------------------------------------------------------------------------------------------------------// -DOC- If you're like me, it's hard to gain trust in foreign code. This memory manager will try to INDUCE your code to crash (for// very good reasons... like making bugs obvious as early as possible.) Some people may be inclined to remove this memory tracking// software if it causes crashes that didn't exist previously. In reality, these new crashes are the BEST reason for using this// software!//// Whether this software causes your application to crash, or if it reports errors, you need to be able to TRUST this software. To// this end, you are given some very simple debugging tools.// // The quickest way to locate problems is to enable the STRESS_TEST macro (below.) This should catch 95% of the crashes before they// occur by validating every allocation each time this memory manager performs an allocation function. If that doesn't work, keep// reading...//// If you enable the TEST_MEMORY_MANAGER #define (below), this memory manager will log an entry in the memory.log file each time it// enters and exits one of its primary allocation handling routines. Each call that succeeds should place an "ENTER" and an "EXIT"// into the log. If the program crashes within the memory manager, it will log an "ENTER", but not an "EXIT". The log will also// report the name of the routine.//// Just because this memory manager crashes does not mean that there is a bug here! First, an application could inadvertantly damage// the heap, causing malloc(), realloc() or free() to crash. Also, an application could inadvertantly damage some of the memory used// by this memory tracking software, causing it to crash in much the same way that a damaged heap would affect the standard// allocation routines.//// In the event of a crash within this code, the first thing you'll want to do is to locate the actual line of code that is// crashing. You can do this by adding log() entries throughout the routine that crashes, repeating this process until you narrow// in on the offending line of code. If the crash happens in a standard C allocation routine (i.e. malloc, realloc or free) don't// bother contacting me, your application has damaged the heap. You can help find the culprit in your code by enabling the// STRESS_TEST macro (below.)//// If you truely suspect a bug in this memory manager (and you had better be sure about it! :) you can contact me at// midnight@FluidStudios.com. Before you do, however, check for a newer version at:////	http://www.FluidStudios.com/publications.html//// When using this debugging aid, make sure that you are NOT setting the alwaysLogAll variable on, otherwise the log could be// cluttered and hard to read.// ---------------------------------------------------------------------------------------------------------------------------------//#define	TEST_MEMORY_MANAGER// ---------------------------------------------------------------------------------------------------------------------------------// -DOC- Enable this sucker if you really want to stress-test your app's memory usage, or to help find hard-to-find bugs// ---------------------------------------------------------------------------------------------------------------------------------#define	STRESS_TEST// ---------------------------------------------------------------------------------------------------------------------------------// -DOC- Enable this sucker if you want to stress-test your app's error-handling. Set RANDOM_FAIL to the percentage of failures you//       want to test with (0 = none, >100 = all failures).// ---------------------------------------------------------------------------------------------------------------------------------//#define	RANDOM_FAILURE 10.0// ---------------------------------------------------------------------------------------------------------------------------------// -DOC- Locals -- modify these flags to suit your needs// ---------------------------------------------------------------------------------------------------------------------------------#ifdef	STRESS_TEST	static	const	unsigned int	hashBits           		= 12;	static			bool			randomWipe          	= true;	static			bool			alwaysValidateAll   	= true;	static			bool			alwaysLogAll        	= true;	static			bool			alwaysWipeAll       	= true;	static			bool			cleanupLogOnFirstRun	= true;	static	const	unsigned int	paddingSize         	= 1024; // An extra 8K per allocation!#else	static	const	unsigned int	hashBits               = 12;	static			bool			randomWipe             = false;	static			bool			alwaysValidateAll      = false;	static			bool			alwaysLogAll           = false;	static			bool			alwaysWipeAll          = true;	static			bool			cleanupLogOnFirstRun   = true;	static	const	unsigned int	paddingSize            = 4;#endif// ---------------------------------------------------------------------------------------------------------------------------------// We define our own assert, because we don't want to bring up an assertion dialog, since that allocates RAM. Our new assert// simply declares a forced breakpoint.//// The BEOS assert added by Arvid Norberg <arvid@iname.com>.// ---------------------------------------------------------------------------------------------------------------------------------#ifdef	WIN32	#ifdef	_DEBUG	#define	m_assert(x) if ((x) == false) __asm { int 3 }	#else	#define	m_assert(x) {}	#endif#elif defined(__BEOS__)	#ifdef DEBUG		extern void debugger(const char *message);		#define	m_assert(x) if ((x) == false) debugger("mmgr: assert failed")	#else		#define m_assert(x) {}	#endif#else	// Linux uses assert, which we can use safely, since it doesn't bring up a dialog within the program.	#define	m_assert(cond) assert(cond)#endif// ---------------------------------------------------------------------------------------------------------------------------------// Here, we turn off our macros because any place in this source file where the word 'new' or the word 'delete' (etc.)// appear will be expanded by the macro. So to avoid problems using them within this source file, we'll just #undef them.// ---------------------------------------------------------------------------------------------------------------------------------#undef	new#undef	delete#undef	malloc#undef	calloc#undef	realloc#undef	free// ---------------------------------------------------------------------------------------------------------------------------------// Defaults for the constants & statics in the MemoryManager class// ---------------------------------------------------------------------------------------------------------------------------------const		unsigned int	m_alloc_unknown        = 0;const		unsigned int	m_alloc_new            = 1;const		unsigned int	m_alloc_new_array      = 2;const		unsigned int	m_alloc_malloc         = 3;const		unsigned int	m_alloc_calloc         = 4;const		unsigned int	m_alloc_realloc        = 5;const		unsigned int	m_alloc_delete         = 6;const		unsigned int	m_alloc_delete_array   = 7;const		unsigned int	m_alloc_free           = 8;// ---------------------------------------------------------------------------------------------------------------------------------// -DOC- Get to know these values. They represent the values that will be used to fill unused and deallocated RAM.// ---------------------------------------------------------------------------------------------------------------------------------static		unsigned int	prefixPattern          = 0xbaadf00d; // Fill pattern for bytes preceeding allocated blocksstatic		unsigned int	postfixPattern         = 0xdeadc0de; // Fill pattern for bytes following allocated blocksstatic		unsigned int	unusedPattern          = 0xfeedface; // Fill pattern for freshly allocated blocksstatic		unsigned int	releasedPattern        = 0xdeadbeef; // Fill pattern for deallocated blocks// ---------------------------------------------------------------------------------------------------------------------------------// Other locals// ---------------------------------------------------------------------------------------------------------------------------------static	const	unsigned int	hashSize               = 1 << hashBits;static	const	char		*allocationTypes[]     = {"Unknown",							  "new",     "new[]",  "malloc",   "calloc",							  "realloc", "delete", "delete[]", "free"};static		sAllocUnit	*hashTable[hashSize];static		sAllocUnit	*reservoir;static		unsigned int	currentAllocationCount = 0;static		unsigned int	breakOnAllocationCount = 0;static		sMStats		stats;static	const	char		*sourceFile            = "??";static	const	char		*sourceFunc            = "??";static		unsigned int	sourceLine             = 0;static		bool		staticDeinitTime       = false;static		sAllocUnit	**reservoirBuffer      = NULL;static		unsigned int	reservoirBufferSize    = 0;static const	char		*memoryLogFile         = "memory.log";static const	char		*memoryLeakLogFile     = "memleaks.log";static		void		doCleanupLogOnFirstRun();// ---------------------------------------------------------------------------------------------------------------------------------// Local functions only// ---------------------------------------------------------------------------------------------------------------------------------static	void	log(const char *format, ...){	// Build the buffer	static char buffer[2048];	va_list	ap;	va_start(ap, format);	vsprintf(buffer, format, ap);	va_end(ap);	// Cleanup the log?	if (cleanupLogOnFirstRun) doCleanupLogOnFirstRun();	// Open the log file	FILE	*fp = fopen(memoryLogFile, "ab");	// If you hit this assert, then the memory logger is unable to log information to a file (can't open the file for some	// reason.) You can interrogate the variable 'buffer' to see what was supposed to be logged (but won't be.)	m_assert(fp);	if (!fp) return;	// Spit out the data to the log	fprintf(fp, "%s\r\n", buffer);	fclose(fp);}// ---------------------------------------------------------------------------------------------------------------------------------static	void	doCleanupLogOnFirstRun(){	if (cleanupLogOnFirstRun)	{		unlink(memoryLogFile);		cleanupLogOnFirstRun = false;		// Print a header for the log		time_t	t = time(NULL);		log("--------------------------------------------------------------------------------");		log("");		log("      %s - Memory logging file created on %s", memoryLogFile, asctime(localtime(&t)));		log("--------------------------------------------------------------------------------");		log("");		log("This file contains a log of all memory operations performed during the last run.");		log("");		log("Interrogate this file to track errors or to help track down memory-related");		log("issues. You can do this by tracing the allocations performed by a specific owner");		log("or by tracking a specific address through a series of allocations and");		log("reallocations.");		log("");		log("There is a lot of useful information here which, when used creatively, can be");		log("extremely helpful.");		log("");		log("Note that the following guides are used throughout this file:");		log("");		log("   [!] - Error");		log("   [+] - Allocation");		log("   [~] - Reallocation");		log("   [-] - Deallocation");		log("   [I] - Generic information");		log("   [F] - Failure induced for the purpose of stress-testing your application");		log("   [D] - Information used for debugging this memory manager");		log("");		log("...so, to find all errors in the file, search for \"[!]\"");		log("");		log("--------------------------------------------------------------------------------");	}}// ---------------------------------------------------------------------------------------------------------------------------------static	const char	*sourceFileStripper(const char *sourceFile){	char	*ptr = strrchr(sourceFile, '\\');	if (ptr) return ptr + 1;	ptr = strrchr(sourceFile, '/');	if (ptr) return ptr + 1;	return sourceFile;}

⌨️ 快捷键说明

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