This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

请教大家,DSP28335运行程序一段时间后,程序突然卡在了malloc和free函数里的while循环里,跳不出来,这种情况是不是由于内存溢出的情况,还是逻辑上的问题?



/*****************************************************************************/

/*      */

/*  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();

}