C Ошибка Realloc - "Утверждение` ptr == alloc_last_block 'не удалось! " - PullRequest
1 голос
/ 05 октября 2010

Я пишу функцию на C, которая берет связанный список и предикат и возвращает массив, содержащий все значения связанного списка, удовлетворяющие этому условию.Вот функция:

void **get_all_that(list_t *l, int (*pred)(const void *)) {
    void **vals = NULL;
    int i = 0; // Number of matches found
    const size_t vps = sizeof(void *);
    node_t *n = l->first;
    while (n) {
        if (pred(n->value)) {
            vals = (void **)realloc(vals, i*vps); // (*)
            vals[i] = n->value;
            i++;
        }
        n = n->next;
    }
    if (vals != NULL) {
        vals = (void **)realloc(vals, i*vps);
        vals[i] = NULL; // NULL-terminate array
    }
    return vals;
}

Я передал предикат, который всегда возвращает 1 (т. Е. Get_all_that, в основном, to_array), и я получаю ошибку в звездной строке на итерации, где i = 4.Ошибка на обратной трассировке (которая была автоматически распечатана из SIGABRT): «*** glibc обнаружено *** ~ / list / test: realloc (): недопустимый следующий размер: 0x0804c0e8 ***»

Iоткрыл GDB, сказав, что он сломается прямо перед вызовом realloc, когда i = 4.Затем я попытался вызвать realloc (vals, i * vps) вручную из GDB и получил сообщение об ошибке: «ld.so: dl-minimal.c: 138 обнаружено несоответствие: realloc: утверждение` ptr == alloc_last_block 'не удалось! »

Кто-нибудь знает, что происходит?

Ответы [ 2 ]

2 голосов
/ 05 октября 2010

Ваш realloc выделяет слишком мало элементов. Попробуйте заменить i на i+1. Вы также должны проверить на наличие ошибки realloc перед заменой указателя, который вы передали ему, так как в противном случае вы получите утечку памяти (не говоря уже о сбое, поскольку вы не можете проверить на NULL) при сбое, и удалите ненужные уродливые броски из возвращаемого значения realloc тоже подойдут.

0 голосов
/ 05 октября 2010

И ваш первый realloc называет длину с 0, что является free. Так что совет ставить i+1 вдвойне важен.

...