📄 memory_util.c
字号:
/* * check for NULL, which should only occur if the system is out * of memory. */ if (!mptr) { printf("ERROR: Pointer is null. Probably out of memory!\n"); exit(EXIT_FAILURE); }/* * Check whether pointer already exists in the memory table. if it does * but in the same position as "current" then everything is ok, i.e. the * system might have used to same pointer for the same memory (i.e. it * defaulted on memory creation, maybe). However, if the pointer exists * anywhere else then something has gone odd. s_alloc_debug() or * s_free_debug() would get screwed up trying to use this pointer. */ i=match_mptr(mptr); if (i==NULL || i==current) return TRUE; if (i) { printf("WARNING: system has duplicated an active table pointer! %p from %s\n", mptr, i->label); printf("WARNING: The table is now corrupted! %d records.\n", num_mem); }/* else { printf("WARNING: Unable to match table pointer! %p\n", mptr); printf("WARNING: The table is now corrupted! %d records.\n", num_mem); }*//* FIXME: reinstate this using tree traversal function. for(j=0;j<num_mem;j++) printf("%d %p %p\n",j,mptr,mem[j].mptr);*/ return FALSE; }/********************************************************************** pad_mptr_low() etc. synopsis: Functions to handle padding. parameters: return: last updated: 01/12/98 **********************************************************************/static void pad_mptr_low(mem_record *mr) { if (mr->pad_ls == 0) return; /* There's nothing to do here. */ (void *)memcpy(((unsigned char *) mr->mptr)-mr->pad_ls,mr->pad_low,mr->pad_ls); return; }static void pad_mptr_high(mem_record *mr) { unsigned char *cmptr; if (mr->pad_hs==0) return; /* There's nothing to do here. */ cmptr=(unsigned char *) mr->mptr; (void *)memcpy(cmptr+mr->rmem,mr->pad_high,mr->pad_hs); return; }static int check_pad_mptr_low(mem_record *mr) { unsigned char *cmptr; if (!mr->pad_ls) return 0; cmptr=(unsigned char *) mr->mptr; return abs( memcmp(cmptr-mr->pad_ls,mr->pad_low,mr->pad_ls) ); }static int check_pad_mptr_high(mem_record *mr) { unsigned char *cmptr; if (!mr->pad_hs) return 0; cmptr=(unsigned char *) mr->mptr; return abs( memcmp(cmptr+mr->rmem,mr->pad_high,mr->pad_hs) ); }static void *bump_down(void *mtemp, int i_size) { unsigned char *bmptr; bmptr = (unsigned char *) mtemp; bmptr -= i_size; return ((void *) bmptr); }static void *bump_up(void *mtemp, int i_size) { unsigned char *bmptr; bmptr = (unsigned char *) mtemp; bmptr += i_size; return ((void *) bmptr); }static void free_padded(mem_record *mr) { unsigned char *bmptr; bmptr = (unsigned char*) mr->mptr; bmptr -= mr->pad_ls; free(bmptr); return; }/********************************************************************** void *s_alloc_debug() synopsis: My replacement for the standard malloc(), calloc() realloc(), and strdup() calls. I have assummed that sizeof(char)==sizeof(byte) which I think is always true. parameters: lots. return: None. last updated: 19/01/99 **********************************************************************/void *s_alloc_debug(memory_alloc_type type, size_t memsize, int numvars, void *mptr, const char *name, const char *file, const int line, const char *label) { mem_record *j=NULL; /* Current memory record. */ size_t size_low, size_high; /* Padding amount. */ char rand_high='a', rand_low='a'; /* Padding value. */ int k; /* Loop variable. */ void *mtemp=NULL; /* Temp. memory pointer. */ int len; /* String length. */#if MEMORY_DEBUG>2 printf("Allocation of %d bytes by method %d.\n", (int) memsize, (int) type);#endif/* Increment call counter */ switch ((int) type) { case (MEMORY_MALLOC): memory_count_malloc++; break; case (MEMORY_CALLOC): memory_count_calloc++; break; case (MEMORY_REALLOC): memory_count_realloc++; break; case (MEMORY_STRDUP): case (MEMORY_STRNDUP): memory_count_strdup++; break; default: printf("ERROR: s_alloc_debug(): Unknown type %d.\n", (int) type); exit(EXIT_FAILURE); }/* * Initialise tree if required. * Remember that this tree is outside the scope of the memory tracing! */ if (memtree==NULL) { memtree_new(); if(!check_mptr(memtree,NULL)) printf("Dodgy memory allocation table!\n"); }/* Check padding preference */ switch (memory_padding) { case 0: size_low=0; size_high=0; break; case 1: size_low=memory_size_pad; size_high=memory_size_pad;/* rand_high=rand(); rand_low=rand();*/ break; case 2: size_low=0; size_high=memory_size_pad;/* rand_high=rand();*/ break; case 3: size_low=memory_size_pad; size_high=0;/* rand_low=rand();*/ break; default: printf("s_alloc_debug(): Unknown memory padding level %d\n", memory_padding); exit(EXIT_FAILURE); } if(memory_bounds==1) memory_check_all_bounds(); if(memory_bounds==3) memory_check_all_bounds();/* Check pointer if we are doing a reallocation */ if(mptr!=NULL && type==MEMORY_REALLOC) { j=match_mptr(mptr);/*printf("Realloc mptr = %p j = %p j->mptr = %p\n", mptr, j, j->mptr);*//* * Handle any non-null, non-registered pointers. */ if (memory_strict && j==NULL) { printf("WARNING: NO match to pointer table for %p \"%s\".\n", mptr, label); if (memory_strict==1) { printf("Assigning memory anyway.\n"); j=NULL; mptr=NULL; } if (memory_strict==2) { printf("Returning with pointer UNASSIGNED.\n"); return mptr; } if (memory_strict==3) { dief("Exiting program.\n"); } }/* * Handle special case of realloc(mptr, 0). */ if (memsize==0) { s_free_debug(mptr, name, file, line); return NULL; } }/* * Add memory by whichever method was requested. * Note that realloc() is NULL-safe. */ if ( mptr==NULL || type==MEMORY_STRDUP || type==MEMORY_STRNDUP ) { switch ((int) type) { case (MEMORY_MALLOC):#if MEMORY_DEBUG>2 printf("Malloc of %d + %d + %d bytes.\n", (int) memsize, (int) size_low, (int) size_high);#endif if ( !(mtemp=malloc(memsize+size_low+size_high)) ) { dief("Memory allocation of %lu bytes failed at func=%s file=%s line=%d\n", (unsigned long) memsize, name, file, line); } break; case (MEMORY_CALLOC): /* We don't use 'mtemp=calloc(memsize,numvars);', * we use malloc instead of calloc */ if ( !(mtemp=malloc(memsize*numvars+size_low+size_high)) ) { dief("Memory allocation of %lu bytes failed at func=%s file=%s line=%d\n", (unsigned long) numvars*memsize, name, file, line); } memset(mtemp,0,memsize*numvars+size_low+size_high); break; case (MEMORY_REALLOC): /* We also use malloc instead of realloc */ if ( !(mtemp=malloc(memsize+size_low+size_high)) ) { dief("Memory allocation of %lu bytes failed at func=%s file=%s line=%d\n", (unsigned long) memsize, name, file, line); } break; case (MEMORY_STRDUP): /* And guess what... We also use malloc for strdup. Wow. */ if ( !(mtemp=malloc(memsize+size_low+size_high)) ) { dief("Strdup of %lu bytes failed at func=%s file=%s line=%d\n", (unsigned long) memsize, name, file, line); } memcpy((char *)mtemp+size_low,mptr,memsize); break; case (MEMORY_STRNDUP): /* ...and strndup. */ len = strlen(mptr); if (memsize > len) memsize=len; if ( !(mtemp=malloc(memsize+size_low+size_high)) ) { dief("Strdup of %lu bytes failed at func=%s file=%s line=%d\n", (unsigned long) memsize, name, file, line); } memcpy((char *)mtemp+size_low,mptr,memsize); ((char *)mtemp)[memsize-1] = '\0'; break; default: dief("s_alloc_debug(): Unknown type %d. This is a bad internal error!\n", (int) type); } mtemp=bump_up(mtemp,size_low); if (!check_mptr(mtemp,NULL)) printf("Dodgy %s\n",label);/* * Fill in memory record for this block. */ j = mem_record_new(); j->mptr=mtemp; j->mem=memsize*numvars; j->rmem=j->mem; strncpy(j->label,label,64); strncpy(j->func,name,64); strncpy(j->file,file,64); j->line=line; j->pad_ls=size_low; j->pad_hs=size_high; if(size_high) { for (k=0; k<size_high; k++) j->pad_high[k]=rand_high; pad_mptr_high(j); } if(size_low) { for (k=0; k<size_low; k++) j->pad_low[k]=rand_low; pad_mptr_low(j); } allocated_mem+=memsize*numvars; if (allocated_mem > most_mem) most_mem = allocated_mem;/*printf("INSERT (1) mtemp = %p j = %p j->mptr = %p\n", mtemp, j, j->mptr);*/ avltree_insert(memtree, (vpointer)j); } else {/* * There is (or should be) a record of this pointer already, therefore * we just update the current entry. */ mtemp=j->mptr;/* DEBUG: */ if (!check_mptr(mtemp,j)) printf("Dodgy %s\n",label);/*printf("mtemp = %p, j = %p, j->mptr = %p\n", mtemp, j, j->mptr);*//* if new memory is required */ if(memsize*numvars>j->mem) { switch ((int) type) { case (MEMORY_MALLOC): /* This case should never happen. */ printf("s_alloc_debug(): MALLOC with existing pointer requested. Internal error?\n"); exit(EXIT_FAILURE); break; case (MEMORY_CALLOC): /* This case should never happen. */ printf("s_alloc_debug(): CALLOC with existing pointer requested. Internal error?\n"); exit(EXIT_FAILURE); break; case (MEMORY_REALLOC): mtemp=bump_down(mtemp,j->pad_ls); mtemp=realloc(mtemp,memsize+size_low+size_high); if (!mtemp) { printf("Memory reallocation of %lu bytes failed at func=%s file=%s line=%d\n", (unsigned long) memsize, name, file, line); perror("realloc"); exit(EXIT_FAILURE); } break; case (MEMORY_STRDUP): /* This case should never happen. */ printf("s_alloc_debug(): STRDUP call in wrong bit of code. Internal error!\n"); exit(EXIT_FAILURE); break; case (MEMORY_STRNDUP): /* This case should never happen. */ printf("s_alloc_debug(): STRNDUP call in wrong bit of code. Internal error!\n"); exit(EXIT_FAILURE); break; default: printf("s_alloc_debug(): Unknown type %d.\n", (int) type); exit(EXIT_FAILURE); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -