Утверждение прервано, когда массив достигает длины 0 в c

Цель этой функции — удалить элемент с наивысшим индексом, который фактически является последним элементом массива. Я запустил этот код с массивом длиной 5, и он работал нормально до тех пор, пока не достиг точки, где длина массива была равна 0. Затем внезапно он сказал, что прервано из-за неудачного утверждения с помощью ia-> данные. Почему это дает мне ошибку утверждения, когда он попадает в массив NULL?

Вот структура моего кода:

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

Вот функция для удаления элемента с самым высоким индексом ниже:

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

person John Claser    schedule 28.11.2014    source источник
comment
может потому что когда len это 0, data это NULL?   -  person Sourav Ghosh    schedule 28.11.2014
comment
Вы уже задавали этот вопрос вчера, и в первом комментарии кто-то сказал вам, что len = ia->len перед проверкой if (ia == NULL) - плохая идея. Кроме того, что вы ожидали получить, вызвав realloc с 0 (кроме NULL)?   -  person barak manos    schedule 28.11.2014


Ответы (1)


len объявляется как unsigned int. Итак, если len равно 0, то строка

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

попытается выделить 4 ГБ на 32-битной машине или какое-то огромное количество памяти на 64-битной машине. В любом случае, если выделение не удается и realloc возвращает NULL, assert не выполняется.

Чтобы избежать этой проблемы, вам нужно обрабатывать len == 0 как особый случай.

person user3386109    schedule 28.11.2014