TI中文支持网
TI专业的中文技术问题搜集分享网站

请教各位大哥大姐,程序运行一段时间后,卡在malloc和free函数中的while里面了,跳不出来,这种情况是不是内存溢出造成的?malloc和free可以频繁使用吗,程序长时间运行,不停的malloc,free会不会有问题?

/*****************************************************************************/
/*      */
/*  MALLOC – Allocate a packet of a given size, and return pointer to it.    */
/*      */
/*****************************************************************************/
void *malloc(size_t size)
{
    memsz_t allocsize;
    PACKET *current, *next, *prev;
    if (check_alloc_size(size) == 0) return 0;
    allocsize = (memsz_t)size;
    if (allocsize == 0) return 0;
    /*———————————————————————–*/
    /* We may need to adjust the size of the allocation request to ensure    */
    /* that the address of the field "next_free" remains strictly aligned    */
    /* in all packets on the free list.      */
    /*———————————————————————–*/
    if ((allocsize ^ OVERHEAD) & 1) ++allocsize;
    _lock();
    if (first_call) minit();
    current = sys_free;
    prev = 0;
    /*———————————————————————–*/
    /* Find the first block large enough to hold the requested allocation    */
    /*———————————————————————–*/
    while (current != LIMIT && -current->packet_size < allocsize)
    {
prev = current;
current = current->next_free;
    }
    if (current == LIMIT)
    {
        /*——————————————————————-*/
        /* No block large enough was found, so return NULL.      */
        /*——————————————————————-*/
_unlock();
return 0;
    }
    if (-current->packet_size > (allocsize + OVERHEAD + MINSIZE))
    {
        /*——————————————————————-*/
        /* The packet is larger than needed; split the block and mark the    */
        /* smaller-addressed block as used.  The smaller-addressed block     */
        /* was chosen as a way to ensure that freed blocks get recycled      */
        /* before allocations are made from the large original free block.   */
        /* However, this may tend to increase the length of the free list    */
        /* search for a large enough block.      */
        /*——————————————————————-*/
        /* Knuth's algorithm 2.5a instead allocates the larger-addressed     */
        /* block to the user.  This tends to leave the largest free blocks   */
        /* at the beginning of the free list.  Knuth's 2.5a' uses a "rover"  */
        /* pointer to prevent small free blocks from being concentrated in   */
        /* any part of the list.      */
        /*——————————————————————-*/
next = (PACKET *)((char *)current + allocsize + OVERHEAD);
next->packet_size=current->packet_size+allocsize+OVERHEAD;/*NEG==FREE*/
#ifdef DEBUG
next->guard = GUARDWORD;
#endif
current->packet_size = allocsize; /* POSITIVE==IN USE */
if (prev) prev->next_free = next;
else      sys_free        = next;
next->next_free = current->next_free;
    }
    else
    {
        /*——————————————————————-*/
        /* Allocate the whole block and remove it from the free list.      */
        /*——————————————————————-*/
if (prev) prev->next_free = current->next_free;
else      sys_free        = current->next_free;
current->packet_size = -current->packet_size; /* POSITIVE==IN USE */
    }
    _unlock();
    return &(current->next_free);
}
/*****************************************************************************/
/*      */
/*  FREE – Return a packet allocated by malloc to free memory pool.      */
/*      */
/*****************************************************************************/
void free(void *userptr)
{
    PACKET *sysblock, *next, *prev;
    if (userptr == 0) return; /* HANDLE NULL POINTER */
    _lock();
    next = sys_free;
    prev = 0;
    sysblock = (PACKET *)((char *)userptr – OVERHEAD);
    /*———————————————————————–*/
    /* Search the free list for the *free* packets physically closest to     */
    /* the packet to be freed.  PREV is the closest free packet with a      */
    /* smaller address, and NEXT is the closest free packet with a larger    */
    /* address.      */
    /*———————————————————————–*/
    while (next < sysblock)
    {
prev = next;
next = next->next_free;
    }
    /*———————————————————————–*/
    /* Coallesce with next block if possible.      */
    /*———————————————————————–*/
    if ((char *)sysblock + sysblock->packet_size + OVERHEAD == (char *)next)
    {
sysblock->next_free = next->next_free;
sysblock->packet_size += -next->packet_size + OVERHEAD; /* POS==USED */
#ifdef DEBUG
next->guard = 0;
#endif
    }
    else sysblock->next_free = next; /* START TO PUT INTO LIST */
    if (prev) /* ARE WE THE NEW HEAD OF THE LIST */
    {
        /*——————————————————————-*/
        /* sysblock is not the head of the free list; try to coallesce with  */
        /* prev      */
        /*——————————————————————-*/
if ((char *)prev – prev->packet_size + OVERHEAD == (char *)sysblock)
{
    prev->next_free = sysblock->next_free;
    prev->packet_size += -sysblock->packet_size – OVERHEAD;/*NEG==FREE*/
#ifdef DEBUG
    sysblock->guard = 0;
#endif
}
else
{
    prev->next_free = sysblock;
    sysblock->packet_size = -sysblock->packet_size; /* NEGATIVE==FREE */
}
    }
    else
    {
sys_free = sysblock;
sysblock->packet_size = -sysblock->packet_size; /* NEGATIVE==FREE */
    }
    _unlock();
}

user6069081:应该不是你malloc,free的问题,如果你malloc了一块内存只要free掉是可以的,可能是卡在while死循环出不来了,这个while语句如果你只想赋值一次的话,建议你用if,如果想循环赋值,建议用for。

/*****************************************************************************/
/*      */
/*  MALLOC – Allocate a packet of a given size, and return pointer to it.    */
/*      */
/*****************************************************************************/
void *malloc(size_t size)
{
    memsz_t allocsize;
    PACKET *current, *next, *prev;
    if (check_alloc_size(size) == 0) return 0;
    allocsize = (memsz_t)size;
    if (allocsize == 0) return 0;
    /*———————————————————————–*/
    /* We may need to adjust the size of the allocation request to ensure    */
    /* that the address of the field "next_free" remains strictly aligned    */
    /* in all packets on the free list.      */
    /*———————————————————————–*/
    if ((allocsize ^ OVERHEAD) & 1) ++allocsize;
    _lock();
    if (first_call) minit();
    current = sys_free;
    prev = 0;
    /*———————————————————————–*/
    /* Find the first block large enough to hold the requested allocation    */
    /*———————————————————————–*/
    while (current != LIMIT && -current->packet_size < allocsize)
    {
prev = current;
current = current->next_free;
    }
    if (current == LIMIT)
    {
        /*——————————————————————-*/
        /* No block large enough was found, so return NULL.      */
        /*——————————————————————-*/
_unlock();
return 0;
    }
    if (-current->packet_size > (allocsize + OVERHEAD + MINSIZE))
    {
        /*——————————————————————-*/
        /* The packet is larger than needed; split the block and mark the    */
        /* smaller-addressed block as used.  The smaller-addressed block     */
        /* was chosen as a way to ensure that freed blocks get recycled      */
        /* before allocations are made from the large original free block.   */
        /* However, this may tend to increase the length of the free list    */
        /* search for a large enough block.      */
        /*——————————————————————-*/
        /* Knuth's algorithm 2.5a instead allocates the larger-addressed     */
        /* block to the user.  This tends to leave the largest free blocks   */
        /* at the beginning of the free list.  Knuth's 2.5a' uses a "rover"  */
        /* pointer to prevent small free blocks from being concentrated in   */
        /* any part of the list.      */
        /*——————————————————————-*/
next = (PACKET *)((char *)current + allocsize + OVERHEAD);
next->packet_size=current->packet_size+allocsize+OVERHEAD;/*NEG==FREE*/
#ifdef DEBUG
next->guard = GUARDWORD;
#endif
current->packet_size = allocsize; /* POSITIVE==IN USE */
if (prev) prev->next_free = next;
else      sys_free        = next;
next->next_free = current->next_free;
    }
    else
    {
        /*——————————————————————-*/
        /* Allocate the whole block and remove it from the free list.      */
        /*——————————————————————-*/
if (prev) prev->next_free = current->next_free;
else      sys_free        = current->next_free;
current->packet_size = -current->packet_size; /* POSITIVE==IN USE */
    }
    _unlock();
    return &(current->next_free);
}
/*****************************************************************************/
/*      */
/*  FREE – Return a packet allocated by malloc to free memory pool.      */
/*      */
/*****************************************************************************/
void free(void *userptr)
{
    PACKET *sysblock, *next, *prev;
    if (userptr == 0) return; /* HANDLE NULL POINTER */
    _lock();
    next = sys_free;
    prev = 0;
    sysblock = (PACKET *)((char *)userptr – OVERHEAD);
    /*———————————————————————–*/
    /* Search the free list for the *free* packets physically closest to     */
    /* the packet to be freed.  PREV is the closest free packet with a      */
    /* smaller address, and NEXT is the closest free packet with a larger    */
    /* address.      */
    /*———————————————————————–*/
    while (next < sysblock)
    {
prev = next;
next = next->next_free;
    }
    /*———————————————————————–*/
    /* Coallesce with next block if possible.      */
    /*———————————————————————–*/
    if ((char *)sysblock + sysblock->packet_size + OVERHEAD == (char *)next)
    {
sysblock->next_free = next->next_free;
sysblock->packet_size += -next->packet_size + OVERHEAD; /* POS==USED */
#ifdef DEBUG
next->guard = 0;
#endif
    }
    else sysblock->next_free = next; /* START TO PUT INTO LIST */
    if (prev) /* ARE WE THE NEW HEAD OF THE LIST */
    {
        /*——————————————————————-*/
        /* sysblock is not the head of the free list; try to coallesce with  */
        /* prev      */
        /*——————————————————————-*/
if ((char *)prev – prev->packet_size + OVERHEAD == (char *)sysblock)
{
    prev->next_free = sysblock->next_free;
    prev->packet_size += -sysblock->packet_size – OVERHEAD;/*NEG==FREE*/
#ifdef DEBUG
    sysblock->guard = 0;
#endif
}
else
{
    prev->next_free = sysblock;
    sysblock->packet_size = -sysblock->packet_size; /* NEGATIVE==FREE */
}
    }
    else
    {
sys_free = sysblock;
sysblock->packet_size = -sysblock->packet_size; /* NEGATIVE==FREE */
    }
    _unlock();
}

mangui zhang:动态内存分配的内存空间是在heap里,如果heap分配的空间太小,分配过程中会产生溢出

/*****************************************************************************/
/*      */
/*  MALLOC – Allocate a packet of a given size, and return pointer to it.    */
/*      */
/*****************************************************************************/
void *malloc(size_t size)
{
    memsz_t allocsize;
    PACKET *current, *next, *prev;
    if (check_alloc_size(size) == 0) return 0;
    allocsize = (memsz_t)size;
    if (allocsize == 0) return 0;
    /*———————————————————————–*/
    /* We may need to adjust the size of the allocation request to ensure    */
    /* that the address of the field "next_free" remains strictly aligned    */
    /* in all packets on the free list.      */
    /*———————————————————————–*/
    if ((allocsize ^ OVERHEAD) & 1) ++allocsize;
    _lock();
    if (first_call) minit();
    current = sys_free;
    prev = 0;
    /*———————————————————————–*/
    /* Find the first block large enough to hold the requested allocation    */
    /*———————————————————————–*/
    while (current != LIMIT && -current->packet_size < allocsize)
    {
prev = current;
current = current->next_free;
    }
    if (current == LIMIT)
    {
        /*——————————————————————-*/
        /* No block large enough was found, so return NULL.      */
        /*——————————————————————-*/
_unlock();
return 0;
    }
    if (-current->packet_size > (allocsize + OVERHEAD + MINSIZE))
    {
        /*——————————————————————-*/
        /* The packet is larger than needed; split the block and mark the    */
        /* smaller-addressed block as used.  The smaller-addressed block     */
        /* was chosen as a way to ensure that freed blocks get recycled      */
        /* before allocations are made from the large original free block.   */
        /* However, this may tend to increase the length of the free list    */
        /* search for a large enough block.      */
        /*——————————————————————-*/
        /* Knuth's algorithm 2.5a instead allocates the larger-addressed     */
        /* block to the user.  This tends to leave the largest free blocks   */
        /* at the beginning of the free list.  Knuth's 2.5a' uses a "rover"  */
        /* pointer to prevent small free blocks from being concentrated in   */
        /* any part of the list.      */
        /*——————————————————————-*/
next = (PACKET *)((char *)current + allocsize + OVERHEAD);
next->packet_size=current->packet_size+allocsize+OVERHEAD;/*NEG==FREE*/
#ifdef DEBUG
next->guard = GUARDWORD;
#endif
current->packet_size = allocsize; /* POSITIVE==IN USE */
if (prev) prev->next_free = next;
else      sys_free        = next;
next->next_free = current->next_free;
    }
    else
    {
        /*——————————————————————-*/
        /* Allocate the whole block and remove it from the free list.      */
        /*——————————————————————-*/
if (prev) prev->next_free = current->next_free;
else      sys_free        = current->next_free;
current->packet_size = -current->packet_size; /* POSITIVE==IN USE */
    }
    _unlock();
    return &(current->next_free);
}
/*****************************************************************************/
/*      */
/*  FREE – Return a packet allocated by malloc to free memory pool.      */
/*      */
/*****************************************************************************/
void free(void *userptr)
{
    PACKET *sysblock, *next, *prev;
    if (userptr == 0) return; /* HANDLE NULL POINTER */
    _lock();
    next = sys_free;
    prev = 0;
    sysblock = (PACKET *)((char *)userptr – OVERHEAD);
    /*———————————————————————–*/
    /* Search the free list for the *free* packets physically closest to     */
    /* the packet to be freed.  PREV is the closest free packet with a      */
    /* smaller address, and NEXT is the closest free packet with a larger    */
    /* address.      */
    /*———————————————————————–*/
    while (next < sysblock)
    {
prev = next;
next = next->next_free;
    }
    /*———————————————————————–*/
    /* Coallesce with next block if possible.      */
    /*———————————————————————–*/
    if ((char *)sysblock + sysblock->packet_size + OVERHEAD == (char *)next)
    {
sysblock->next_free = next->next_free;
sysblock->packet_size += -next->packet_size + OVERHEAD; /* POS==USED */
#ifdef DEBUG
next->guard = 0;
#endif
    }
    else sysblock->next_free = next; /* START TO PUT INTO LIST */
    if (prev) /* ARE WE THE NEW HEAD OF THE LIST */
    {
        /*——————————————————————-*/
        /* sysblock is not the head of the free list; try to coallesce with  */
        /* prev      */
        /*——————————————————————-*/
if ((char *)prev – prev->packet_size + OVERHEAD == (char *)sysblock)
{
    prev->next_free = sysblock->next_free;
    prev->packet_size += -sysblock->packet_size – OVERHEAD;/*NEG==FREE*/
#ifdef DEBUG
    sysblock->guard = 0;
#endif
}
else
{
    prev->next_free = sysblock;
    sysblock->packet_size = -sysblock->packet_size; /* NEGATIVE==FREE */
}
    }
    else
    {
sys_free = sysblock;
sysblock->packet_size = -sysblock->packet_size; /* NEGATIVE==FREE */
    }
    _unlock();
}

Xiao Dong:嵌入式实时固件一般不用动态内存分配,全部用静态内存分配。

赞(0)
未经允许不得转载:TI中文支持网 » 请教各位大哥大姐,程序运行一段时间后,卡在malloc和free函数中的while里面了,跳不出来,这种情况是不是内存溢出造成的?malloc和free可以频繁使用吗,程序长时间运行,不停的malloc,free会不会有问题?
分享到: 更多 (0)