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 + -
显示快捷键?