Assertion aborted when array reaches length of 0 in c

626 views Asked by At

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;
}
2

There are 2 answers

0
user3386109 On BEST ANSWER

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.

0
user3629249 On
per this link:
<https://www.securecoding.cert.org/confluence/display/seccode/MEM04-C.+Beware+of+zero-length+allocations>   

When the requested size is 0, 
the behavior of the memory allocation functions malloc(), calloc(), and realloc() 
is implementation-defined. 

Subclause 7.22.3 of the C Standard [ISO/IEC 9899:2011] states:

If the size of the space requested is zero, the behavior is implementation-defined: 
either a null pointer is returned, 
or the behavior is as if the size were some nonzero value, 
except that the returned pointer shall not be used to access an object.

it seems that your implementation returns NULL when the allocation size is 0