malloc.c
来自「完整的Bell实验室的嵌入式文件系统TFS」· C语言 代码 · 共 547 行 · 第 1/2 页
C
547 行
} } if (mptr->prev) { if ((mptr->prev->size > 0) && (mptr->prev == (struct mhdr *) ((char *)mptr-mptr->prev->size-sizeof(struct mhdr)))) { if (mptr->next) mptr->next->prev = mptr->prev; mptr->prev->next = mptr->next; mptr->prev->size += mptr->size + sizeof(struct mhdr); } }}/* calloc(): * Allocate space for an array of nelem elements of size elsize. * Initialize the space to zero. */char *calloc(int nelem, int elsize){ register char *cp, *end; char *base; int size; size = nelem * elsize; base = malloc(size); if (base) { cp = base; end = base+size; while(cp<end) *cp++ = 0; } return(base);}char *realloc(char *cp,int size){ char *new; int asize; struct mhdr *mptr; /* If incoming pointer is NULL, then do a regular malloc. */ if (!cp) return(malloc(size)); /* If size is zero and pointer is not null, then do a free. */ if (!size) { free(cp); return((char *)0); } mptr = (struct mhdr *)cp - 1; /* Start by checking sanity of heap and make sure that the incoming * pointer corresponds to a valid entry in the heap. */ if (heapcheck(mptr,0) < 0) return((char *)0); /* Recall that mptr->size is negative since the block is not free, so * use the absolute value of mptr->size... */ asize = abs(mptr->size); /* If new size is less than or equal to current size, just return with * the same pointer. At some point, this should be improved so that * the memory made made available by this reallocation is put back in * the pool. */ if (size <= asize) return(cp); /* First, see if the next fragment after this one is large enough to * support the additional space. */ /* NOT SUPPORTED YET */ /* If the next fragment is not large enough, then malloc new space, * copy the existing data to that block, free the old space and return * a pointer to the new block. */ new = malloc(size); if (!new) return((char *)0); memcpy(new,cp,asize); free(cp); return(new);}voidheapdump(int full){ register struct mhdr *mptr; char freenow; int i, alloctot, freetot, size; heapcheck(0,0); mptr = heapbase; i=0; freetot = 0; alloctot = 0; if (full) printf(" addr size free? mptr nxt prv ascii@addr\n"); else printf("Heap summary:\n"); for(i=0;mptr;i++) { if (mptr->size < 0) { freenow = 'n'; size = -mptr->size; alloctot += size; } else { freenow = 'y'; size = mptr->size; freetot += size; } if (full) { printf("%3d: 0x%08lx %5d %c 0x%08lx 0x%08lx 0x%08lx ", i,(ulong)(mptr+1),size,freenow,(ulong)mptr, (ulong)(mptr->next),(ulong)(mptr->prev)); prascii((unsigned char *)(mptr+1),size > 16 ? 16 : size); putchar('\n'); } mptr = mptr->next; } if (full) putchar('\n'); printf(" Malloc/free calls: %d/%d (delta=%d)\n", mcalls,fcalls,mcalls-fcalls); printf(" Malloc/free totals: %d/%d\n",mtot,ftot); printf(" High-water level: %d\n",highwater); printf(" Malloc failures: %d\n",mfails); printf(" Bytes overhead: %d\n",i*sizeof(struct mhdr)); printf(" Bytes currently allocated: %d\n",alloctot); printf(" Bytes free on current heap: %d\n",freetot); printf(" Bytes left in allocation pool: %d\n",GetMemoryLeft());}/* releaseExtendedHeap(): * If memory has been allocated through the extended heap established * by the heap -x{start,size} command, this function will attempt * to "undo" that. It can only be un-done if there is no currently active * allocations in that range. * * This function is accessible by the application through monlib. */intreleaseExtendedHeap(int verbose){ int i; struct mhdr *mptr, *extbase; extbase = (struct mhdr *)getExtHeapBase(); if (!extbase) { if (verbose) printf("Heap extension not set\n"); return(-1); } heapcheck(0,0); mptr = heapbase; for(i=0;mptr;i++) { if (mptr->next == extbase) { if (mptr->next->next == (struct mhdr *)0) { mptr->next = (struct mhdr *)0; unExtendHeap(); if (verbose) printf("Heap extension cleared\n"); return(0); } else if (verbose) printf("Extended heap space is in use.\n"); break; } mptr = mptr->next; } if ((!mptr) && (verbose)) { /* Heap was extended, but not used. */ unExtendHeap(); /* Remove the extension. */ printf("Heap extension cleared.\n"); } return(0);}char *HeapHelp[] = { "Display heap statistics.", "-[cf:m:vX:x]", "Options:", " -c clear high-water level and malloc/free totals", " -f{ptr} free block @ 'ptr'", " -m{size} malloc 'size' bytes", " -v verbose (more detail)", " -X{base,size}", " extend heap by 'size' bytes starting at 'base'", " -x clear heap extension", 0};intHeap(int argc,char *argv[]){ char *establish_extended_heap, buf[32]; int verbose, release_extended_heap, showheap, opt; showheap = 1; establish_extended_heap = (char *)0; release_extended_heap = verbose = 0; while((opt=getopt(argc,argv,"cf:m:vX:x")) != -1) { switch(opt) { case 'c': mcalls = fcalls = 0; mtot = ftot = highwater = 0; showheap = 0; break; case 'f': free((char *)strtoul(optarg,0,0)); showheap = 0; break; case 'm': shell_sprintf("MALLOC","0x%lx", (ulong)malloc(strtoul(optarg,0,0))); if (verbose) printf("%s\n",buf); showheap = 0; break; case 'v': verbose = 1; break; case 'X': establish_extended_heap = optarg; showheap = 0; break; case 'x': release_extended_heap = 1; showheap = 0; break; default: return(CMD_PARAM_ERROR); } } if (release_extended_heap) releaseExtendedHeap(verbose); if (establish_extended_heap) { int size; char *comma, *begin; comma = strchr(establish_extended_heap,','); if (!comma) return(CMD_PARAM_ERROR); *comma = 0; begin = (char *)strtoul(establish_extended_heap,0,0); size = (int)strtoul(comma+1,0,0); if (extendHeap(begin,size) == -1) { printf("Extended heap already exists @ 0x%lx\n", (ulong)getExtHeapBase()); return(CMD_FAILURE); } } if (!showheap) return(CMD_SUCCESS); if (optind == argc) heapdump(verbose); return(CMD_SUCCESS);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?