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

📄 utmem.c

📁 DataDraw is an ultra-fast persistent database for high performance programs written in C. It s so fa
💻 C
字号:
/* * This file was written by Bill Cox, originally in 1991, and maintained since.  It is hereby * placed into the public domain. */#include <string.h>#include <stdlib.h>#include "ddutil.h"struct utMem_ *utMems;uint32 utfFreeMem, utfVirgMem_, utmMem;struct utStack_ *utStacks;uint32 utsStack, utmStack;static utStackRef utBotStack;static uint32 utMaxMem;uint32 utUsedMem;uint32 utMemSeed = 42;/*--------------------------------------------------------------------------------------------------  Create a new mem.--------------------------------------------------------------------------------------------------*/utMemRef utcMem (void){   utMemRef mem;   if (uttMemExists(utfFreeMem())) {      mem = utfFreeMem();      utfFreeMem() = utnFreeMem(mem);   } else {      if (utfVirgMem() == utmMem()) {         utmMem() += utmMem()/2;         utMems = (struct utMem_ *)realloc((void *)utMems,               utmMem()*sizeof(struct utMem_));         if (!utMems) {            utExit("utcMem: Can't allocate memory handle");         }      }      mem = utfVirgMem()++;   }   uttMemUsed(mem) = true;   return mem;}/*--------------------------------------------------------------------------------------------------  Delete a mem (put it on the free list).--------------------------------------------------------------------------------------------------*/void utdMem (   utMemRef mem,   bool farHeap,   char *fileName,   uint32 line){   utStackRef stack = utlStack();   uint8 rightPicket = *(((uint8 *)utgMemPtr(mem)) + utgMemSize(mem) - 1);   utUsedMem -= utgMemSize(mem);   if (!uttMemUsed(mem)) {      utExit("utdMem: Memory allocated in %s on line %u freed second time "            "in %s on line %u", utgMemName(mem),            utgMemLine(mem), fileName, line);   }   if (utgMemPicket(mem) != rightPicket) {      utExit("utdMem: Memory allocated in %s on line %u and freed in %s "            "line %u lost right picket", utgMemName(mem),            utgMemLine(mem), fileName, line);   }   if (uttMemFarHeap(mem) && !farHeap) {      utExit("utdMem: Far memory allocated in %s on line %u is freed in %s "            "line %u to the near heap", utgMemName(mem),            utgMemLine(mem), fileName, line);   }   if (!uttMemFarHeap(mem) && farHeap) {      utExit("utdMem: Near memory allocated in %s on line %u is freed in %s "            "line %u to the far heap", utgMemName(mem),            utgMemLine(mem), fileName, line);   }   utdStackMem(stack, mem, fileName, line);   utnFreeMem(mem) = utfFreeMem();   utfFreeMem() = mem;   uttMemUsed(mem) = false;   free(utgMemName(mem));}/*--------------------------------------------------------------------------------------------------  Set the seed.  Set the signature to 0;--------------------------------------------------------------------------------------------------*/void utMemInitSeed (   uint32 seed){   if (seed == 0) {      utMemSeed = 1;   } else {      utMemSeed = seed;   }}/*--------------------------------------------------------------------------------------------------  Return a random number between 1 and 2^23 - 1. Specific to             utMem functions so that users utSeed is not affected.--------------------------------------------------------------------------------------------------*/uint32 utMemRand (void){   utMemSeed = (((((utMemSeed << 5) ^ utMemSeed) & 0x7FFF80) >> 7) |                (utMemSeed << 16)) & 0x7FFFFF;   return utMemSeed;}/*--------------------------------------------------------------------------------------------------  Create a new mem, filling in all fields.  Note that the calling routine is responsible for  putting the pickets in memory.--------------------------------------------------------------------------------------------------*/utMemRef utBuildMem (   void *memPtr,   uint32 size,   bool farHeap,   char *file,   uint32 line){   utMemRef mem = utcMem();   utAssert(size > 1);   utAssert(file != NULL && *file != '\0');   utgMemPtr(mem) = memPtr;   utgMemSize(mem) = size;   utUsedMem += size;   if (utUsedMem > utMaxMem) {      utMaxMem = utUsedMem;   }   utgMemLine(mem) = line;   utgMemName(mem) = malloc((strlen(file) + 1)*sizeof(char));   strcpy(utgMemName(mem), file);   utaStackMem(utlStack(), mem);   utgMemPicket(mem) = (uint8)utMemRand();   *(((uint8 *)memPtr) + size - 1) = utgMemPicket(mem);   uttMemFarHeap(mem) = farHeap;   return mem;}/*--------------------------------------------------------------------------------------------------  Find a mem with the same memory pointer.--------------------------------------------------------------------------------------------------*/utMemRef utqMemPtr (   void *memPtr){   utStackRef stack = utlStack();   utMemRef mem;   for (mem = utfStackMem(stack); uttMemExists(mem);         mem = utnStackMem(stack, mem)) {      if (utgMemPtr(mem) == memPtr) {         return mem;      }   }   return ut0Mem;}/*--------------------------------------------------------------------------------------------------  Create a new stack.--------------------------------------------------------------------------------------------------*/utStackRef utcStackTrace (   char *fileName,   uint32 line){   utStackRef stack;   if (utsStack() == utmStack()) {      utmStack() += utmStack()/2;      utStacks = (struct utStack_ *)realloc((void *)utStacks, utmStack()*sizeof(struct utStack_));      if (!utStacks) {         utExit("utcStackTrace: Can't allocate a new stack");      }   }   stack = utsStack()++;   utfStackMem(stack) = ut0Mem;   utgStackName(stack) = malloc((strlen(fileName) + 1)*sizeof(char));   strcpy(utgStackName(stack), fileName);   utgStackLine(stack) = line;   return stack;}/*--------------------------------------------------------------------------------------------------  Delete a stack.  Check for memory errors.--------------------------------------------------------------------------------------------------*/void utdStackTrace (   utStackRef stack,   char *fileName,   uint32 line){   utMemRef mem;   bool error = false;   for (mem = utfStackMem(stack); uttMemExists(mem);         mem = utnStackMem(stack, mem)) {      error = true;      utExit("utdStack: Failed to free memory allocated in %s on line %u",            utgMemName(mem), utgMemLine(mem));   }   if (stack != utlStack()) {      error = true;      utExit("utdStack: Stack allocated in %s on line %u is freed out of "            "order in %s on line %u", utgStackName(stack),            utgStackLine(stack), fileName, line);   }   if (error) {      utExit("utdStack: Punting due to memory errors");   }   free(utgStackName(stack));   utAssert(utsStack() > 0);   utsStack()--;}/*--------------------------------------------------------------------------------------------------  Add a mem to a stack.--------------------------------------------------------------------------------------------------*/void utaStackMem (   utStackRef stack,   utMemRef mem){   utoStackMem(mem) = stack;   utnStackMem(stack, mem) = utfStackMem(stack);   utfStackMem(stack) = mem;}/*--------------------------------------------------------------------------------------------------  Remove a mem from a stack.--------------------------------------------------------------------------------------------------*/void utdStackMem (   utStackRef stack,   utMemRef mem,   char *fileName,   uint32 line){   utMemRef pMem, nMem;   pMem = ut0Mem;   for (nMem = utfStackMem(stack);        uttMemExists(nMem) && nMem != mem;        nMem = utnStackMem(stack, nMem)) {      pMem = nMem;   }   if (nMem != mem) {      utExit("utdStackMem: Memory allocated in %s on line %u does not "            "belong to the stack allocated in %s on line %u.  Look at "            "%s line %u", utgMemName(mem), utgMemLine(mem),            utgStackName(stack), utgStackLine(stack),            fileName, line);   }   if (uttMemExists(pMem)) {      utnStackMem(stack, pMem) = utnStackMem(stack, mem);   } else {      utfStackMem(stack) = utnStackMem(stack, mem);   }}/*--------------------------------------------------------------------------------------------------  Allocate initail memory for mems.--------------------------------------------------------------------------------------------------*/static void allocateMems (void){   utfFreeMem() = ut0Mem;   utfVirgMem() = 0;   utmMem() = 100;   utMems = (struct utMem_ *)calloc(utmMem(), sizeof(struct utMem_));   if (!utMems) {      utExit("allocateMems: Out of memory");   }}/*--------------------------------------------------------------------------------------------------  Allocate initail memory for stacks.--------------------------------------------------------------------------------------------------*/static void allocateStacks (void){   utsStack() = 0;   utmStack() = 100;   utStacks = (struct utStack_ *)calloc(utmStack(), sizeof(struct utStack_));   if (!utStacks) {      utExit("allocateStacks: Out of memory");   }}/*--------------------------------------------------------------------------------------------------  Initialize the memory checker module;--------------------------------------------------------------------------------------------------*/void utMemStart(void){   allocateMems();   allocateStacks();   utBotStack = utcStack();   utUsedMem = 0;   utMaxMem = 0;}/*--------------------------------------------------------------------------------------------------  Free memory used by the memory checker.--------------------------------------------------------------------------------------------------*/void utMemStop(    bool reportMemory){   utdStack(utBotStack);   free((void *)utMems);   free((void *)utStacks);   if(reportMemory) {       utLogMessage("Used %s of memory", utMemoryUnits(utMaxMem));   }}/*--------------------------------------------------------------------------------------------------  Perform a memory check.  Basically, check all the pickets.--------------------------------------------------------------------------------------------------*/void utMemCheckTrace (   char *fileName,   uint32 line){   utStackRef stack;   utMemRef mem;   uint8 picket;   for (stack = utfStack(); uttStackExists(stack); stack = utnStack(stack)) {      for (mem = utfStackMem(stack); uttMemExists(mem);            mem = utnStackMem(stack, mem)) {         picket = *(((uint8 *)utgMemPtr(mem)) + utgMemSize(mem) - 1);         if (picket != utgMemPicket(mem)) {            utExit("utMemCheck: Invoked from %s, line %u: Picket hosed for "                  "memory allocated in %s, " "line %u", fileName, line,                  utgMemName(mem), utgMemLine(mem));         }      }   }}

⌨️ 快捷键说明

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