📄 rmalloc.c.svn-base
字号:
} } }#if RM_TEST_DEPTH > 0 /* Die LOUD */ if (DoAbort) { abort(); }#endif}#if RM_TEST_DEPTH > 0void Rmalloc_stat(const char *file);void freeallall(void);/* ============================================================================= Function: Exit // local // Author: Rammi Date: 08/19/1997 Return: --- Parameter: --- Purpose: Function called on exit ============================================================================= */static void Exit(void){ freeallall(); Rmalloc_stat("[atexit]"); /* show statistics */}//static void freeall()//{// freeallall();//}/* ============================================================================= Function: Initialize // local // Author: Rammi Date: 11.04.1996 Return: --- Parameter: --- Purpose: Necessary initializations ============================================================================= */static void Initialize(void){ int i; fprintf(stderr, HEAD "rmalloc -- malloc wrapper V " VERSION "\n" "\tby Rammi <mailto:rammi@hexco.de>\n" "\tCompiled with following options:\n"#if RM_TEST_DEPTH==1 "\t\ttesting:\tonly actual block\n"#elif RM_TEST_DEPTH==2 "\t\ttesting:\tall allocated blocks\n"#else "\t\ttesting:\tcomment missing in " __FILE__ ":" INT2STRING(__LINE__) "\n"#endif#ifdef GENERATIONS "\t\tgenerations:\tON\n"#else "\t\tgenerations:\tOFF\n"#endif#ifdef ELOQUENT "\t\teloquence:\tON\n"#else "\t\teloquence:\tOFF\n"#endif#ifdef ALLOW_REALLOC_NULL "\t\trealloc(0):\tALLOWED\n"#else "\t\trealloc(0):\tNOT ALLOWED\n"#endif#ifdef ALLOW_FREE_NULL "\t\tfree(0):\tALLOWED\n"#else "\t\tfree(0):\tNOT ALLOWED\n"#endif#ifdef WITH_FLAGS "\t\tflags: \tUSED\n"#else "\t\tflags: \tUNUSED\n"#endif "\t\talignment:\t" INT2STRING(ALIGNMENT) "\n" "\t\tpre space:\t%d\n" "\t\tpost space:\t%d\n" "\t\thash tab size:\t" INT2STRING(HASHSIZE) "\n\n", (short)START_SPACE, (short)END_SPACE); /* --- init list heads --- */ for (i = 0; i < HASHSIZE; i++) { memcpy(Chain+i, &ChainTempl, sizeof(begin)); Chain[i].Next = Chain[i].Prev = Chain+i; } /* --- show statistics at exit --- */ // (void)atexit(freeall); (void)atexit(Exit); Global.isInitialized = 1;}/* ============================================================================= Function: TestAll // local // Author: Rammi Date: 16.11.1995 Return: --- Parameter: file file pos where lib function was called Purpose: Test all allocated blocks for inconsistencies ============================================================================= */static void TestAll(const char *file){ begin *B; int i; for (i = 0; i < HASHSIZE; i++) { B = Chain[i].Next; /* === Once around the circle === */ while (B != &Chain[i]) { ControlBlock(B, file); B = B->Next; } }}/* ============================================================================= Function: AddBlk // local // Author: Rammi Date: 16.11.1995 Return: --- Parameter: Blk New block (original pos.) file called from Purpose: Add new block to the list ============================================================================= */static void AddBlk(begin *Blk, const char *file){ int hash = HASH(Blk); /* hash val */ if (!Global.isInitialized) { Initialize(); }#if RM_TEST_DEPTH > 1 TestAll(file);#endif /* --- insert it --- */ Blk->Next = Chain[hash].Next; Blk->Prev = &Chain[hash]; Chain[hash].Next->Prev = Blk; Chain[hash].Next = Blk; Global.BlockCount++;}/* ============================================================================= Function: DelBlk // local // Author: Rammi Date: 16.11.1995 Return: --- Parameter: Blk block to remove file called from Purpose: Remove block from list. React angry if block is unknown ============================================================================= */static void DelBlk(begin *Blk, const char *file){ begin *B; /* run var */ int hash = HASH(Blk); /* hash val */ /* look if block is known */ for (B = Chain[hash].Next; B != &Chain[hash]; B = B->Next) { if (B == Blk) { goto found_actual_block; /* friendly goto */ } } /* not found */ fprintf(stderr, HEAD "Double or false delete\n" "\tHeap adress of block: %p\n" "\tDetected in %s\n", ((char *)Blk)+START_SPACE, file); { void (*old_sigsegv_handler)(int) = SIG_DFL; void (*old_sigbus_handler)(int) = SIG_DFL; if (setjmp(errorbuf)) { /* uh oh, we got a kick in the ass */ signal(SIGSEGV, old_sigsegv_handler); signal(SIGBUS, old_sigbus_handler); } else {// /* --- the following is dangerous! So catch signals --- */// old_sigsegv_handler = signal(SIGSEGV, FatalSignal);// old_sigbus_handler = signal(SIGBUS, FatalSignal);//// if (IsPossibleFilePos(Blk->File, Blk->Size)) {// fprintf(stderr,// "\tTrying identification (may be incorrect!):\n"// "\t\tAllocated in %s [%u Bytes]\n",// Blk->File, (unsigned) Blk->Size);// }// signal(SIGSEGV, old_sigsegv_handler);// signal(SIGBUS, old_sigbus_handler); } } abort(); /* die loud */found_actual_block:#if RM_TEST_DEPTH > 1 /* check everything */ TestAll(file);#else /* test integrity of actual block */ ControlBlock(Blk, file);#endif /* remove: */ Blk->Next->Prev = Blk->Prev; Blk->Prev->Next = Blk->Next; Global.BlockCount--;#ifdef ELOQUENT fprintf(stderr, HEAD "Delete: %lu Bytes allocated in %s (from %s)\n", Blk->Size, Blk->File, file);#ifdef WITH_FLAGS if (Blk->Flags & RM_STRING) { char *c; /* look for eos */ for (c = (char *)Blk + START_SPACE; c - (char *)Blk + START_SPACE < Blk->Size; c++) { if (!*c) { fprintf(stderr, HEAD "\tContains string: \"%s\"\n", (char *)Blk + START_SPACE); goto found_old_block; } } /* not found */ fprintf(stderr, HEAD "\tContains string without null byte\n");found_old_block: ; }#endif /* WITH_FLAGS */#endif /* ELOQUENT */#ifdef WITH_FLAGS if (Blk->Flags & RM_STATIC) { fprintf(stderr, HEAD "WARNING: freeing block marked as STATIC (in %s)\n", file); }#endif /* WITH_FLAGS */}/* ============================================================================= Function: FindBlk // local // Author: Rammi Date: 11/30/1996 Return: 0 not found 1 found Parameter: P block (user pos) Purpose: look if block is known ============================================================================= */static int FindBlk(const unsigned char *P){ begin *B; const begin *Blk = (const begin *)(P - START_SPACE); int hash = HASH(Blk); /* look if block is known */ for (B = Chain[hash].Next; B != &Chain[hash]; B = B->Next) { if (B == Blk) { return 1; } } return 0;}#endif /* RM_TEST_DEPTH > 0 */#ifdef GENERATIONS/* ============================================================================= Function: rmalloc_generation // local // Author: Karl Brace Date: 04/22/2002 Return: --- Parameter: Blk pointer to block Purpose: Breakpoint for debugger if using Karl's generations feature. ============================================================================= */void rmalloc_generation (void *Blk){ fprintf(stderr, HEAD "Allocating Block with generation %u...\n", ((begin *)Blk)->Generation);}#endif /* GENERATIONS *//* ============================================================================= Function: SetBlk // local // Author: Rammi Date: 11/16/1995 Return: pointer to block (user pos.) Parameter: Blk pointer to block (original pos.) size size (user) file called from flags flags (when compiled WITH_FLAGS) Purpose: Set our internal information ============================================================================= */#ifdef WITH_FLAGSstatic void *SetBlk(void *Blk, size_t size, const char *file, unsigned flags)#elsestatic void *SetBlk(void *Blk, size_t size, const char *file)#endif{ ((begin *)Blk)->StpA = PREV_STOP;#ifdef GENERATIONS ((begin *)Blk)->Generation = ++cur_generation;#endif ((begin *)Blk)->File = file; ((begin *)Blk)->Size = size;#ifdef WITH_FLAGS ((begin *)Blk)->Flags = flags;#endif ((begin *)Blk)->StpB = PREV_STOP; memcpy(((char *)Blk)+START_SPACE+size, End, END_SPACE);#if RM_TEST_DEPTH > 0 AddBlk((begin *)Blk, file);#endif#ifdef ELOQUENT fprintf(stderr, HEAD "Adding: %p, %lu Bytes (from %s)\n", ((char *)Blk)+START_SPACE, size, file);#endif /* ELOQUENT */#ifdef GENERATIONS if (BREAK_GENERATION_COND(cur_generation)) { rmalloc_generation(Blk); }#endif return ((char *)Blk)+START_SPACE;}/* ============================================================================= Function: Rmalloc // external // Author: Rammi Date: 11/16/1995 Return: New prepared memory block with size size (user) Parameter: size demanded size file called from where? Purpose: wrapper for malloc ============================================================================= */void *Rmalloc(size_t size, const char *file){ void *ret; /* ret val */ if (size == 0) { fprintf(stderr, HEAD "WARNING: malloc() demands 0 Bytes (in %s)\n", file); } ret = malloc(size+EXTRA_SPACE); /* get extended block */ if (ret) { /* initialize */#ifdef WITH_FLAGS return SetBlk(ret, size, file, 0);#else return SetBlk(ret, size, file);#endif } else { fprintf(stderr, HEAD "WARNING: Out of memory! Returning NULL (in %s)\n", file); return NULL; }}/* ============================================================================= Function: Rcalloc // external // Author: Rammi Date: 11/16/1995 Return: New (cleared) memory block of size nelem*size Parameter: nelem nr blocks (as stupid as calloc) size size of one block file called from Purpose: Wrapper function for calloc ============================================================================= */void *Rcalloc(size_t nelem, size_t size, const char *file){ void *ret; /* calculate correct size now */ size *= nelem; if (size == 0) { fprintf(stderr, HEAD "WARNING: calloc() demands 0 Bytes (in %s)\n", file); } /* Rmalloc makes nearly all the work */ ret = Rmalloc(size, file); if (ret) { /* clear */ memset(ret, 0, size); return ret; } else { fprintf(stderr, HEAD "WARNING: Out of memory! Returning NULL (in %s)\n", file); return NULL; }}/* ============================================================================= Function: Rrealloc // external // Author: Rammi Date: 11/16/1995 Return: New block of size size (user pos.) Parameter: p previous pointer size new size file called from Purpose: Wrapper function for realloc ============================================================================= */void *Rrealloc(void *p, size_t size, const char *file){ void *ret;#ifdef WITH_FLAGS unsigned flags = 0;#endif if (p == NULL) {#ifndef ALLOW_REALLOC_NULL fprintf(stderr, HEAD "Realloc of NULL pointer (in %s)\n", file); abort();#else /* ALLOW_REALLOC_NULL */#ifdef ELOQUENT fprintf(stderr, HEAD "WARNING: realloc of NULL pointer (in %s)\n", file);#endif return Rmalloc(size, file);#endif /* ALLOW_REALLOC_NULL */ }#ifdef WITH_FLAGS else { /* keep flags */ flags = ((begin *)(((char *)p)-START_SPACE))->Flags; ((begin *)(((char *)p)-START_SPACE))->Flags &= ~RM_STATIC; /* unsetstatic flag to avoid warning */ }#endif /* WITH_FLAGS */ if (size == 0) { fprintf(stderr, HEAD "WARNING: realloc() demands 0 Bytes (in %s)\n", file); }#if RM_TEST_DEPTH > 0 /* remove old block from list */ DelBlk((begin *)(((char *)p)-START_SPACE), file);#endif /* get everything new */ ret = realloc(((char *)p)-START_SPACE, size+EXTRA_SPACE); if (ret) { /* Initialize new block */#ifdef WITH_FLAGS return SetBlk(ret, size, file, flags);#else return SetBlk(ret, size, file);#endif } else { fprintf(stderr, HEAD "WARNING: Out of memory! Returning NULL (in %s)\n", file); return NULL; }}/* ============================================================================= Function: Rfree // external // Author: Rammi Date: 11/16/1995 Return: --- Parameter: p block to free (user pos.) file called from Purpose: Wrapper function for free() ============================================================================= */void Rfree(void *p, const char *file){#ifdef ELOQUENT fprintf(stderr, HEAD "Free: %p (called from: %s)\n", p, file);#endif /* ELOQUENT */ if (p == NULL) {#ifdef ALLOW_FREE_NULL#ifdef ELOQUENT fprintf(stderr, HEAD "WARNING: Freeing NULL pointer (in %s)\n", file);#endif return;#else /* !ALLOW_FREE_NULL */ fprintf(stderr, HEAD "Trying to free NULL pointer (in %s)\n", file); abort();#endif /* !ALLOW_FREE_NULL */ }#if RM_TEST_DEPTH > 0 /* Remove block from list */ DelBlk((begin *)(((char *)p)-START_SPACE), file);#endif /* free block */ free(((char *)p)-START_SPACE);}/* ============================================================================= Function: Rstrdup // external // Author: Rammi Date: 11/16/1995
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -