Search code examples
carraysstructabortassertion

Assertion aborted when array reaches length of 0 in c


The purpose of this function is to remove the element with the highest index, which is basically the last element of the array. I ran this code with an array of length 5, and it ran fine all the way until it reached the point where the length of the array was 0. Then all of a sudden, it said aborted because of a failed assertion with ia->data. Why is it giving me an assertion error when it gets to a NULL array?

Here's the struct for my code:

typedef struct {
  int* data;
  unsigned int len;
} intarr_t;

Here is the function to remove the element with the highest index below:

intarr_result_t intarr_pop( intarr_t* ia, int* i )
{
    unsigned int len = ia->len;
    if (ia == NULL)
    {
        return INTARR_BADARRAY;
    }
    else
    {
        ia->data = realloc(ia->data, (sizeof(int)*(len-1)));
        assert (ia->data);
        if (ia->data != 0)
        {
            if (i != 0)
            {
                *i = ia->data[len-1]
                ia->len = len-1;
                return INTARR_OK;
            }
        }
        else
        {
            return INTARR_BADINDEX;
        }
    }
    return 0;
}

Solution

  • len is declared as an unsigned int. So if len is equal to 0, then the line

    ia->data = realloc(ia->data, (sizeof(int)*(len-1)));   
                                               ^ (len-1) underflows if len == 0
    

    will try to allocate 4GB on a 32-bit machine, or some huge amount of memory on a 64-bit machine. Either way, if the allocation fails and realloc returns NULL, the assert will fail.

    To avoid the problem, you need to handle len == 0 as a special case.