Я пишу функцию на 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 ***»
Я открыл GDB, сказав, что он должен сломаться прямо перед вызовом realloc, когда i=4. Затем я попытался вручную вызвать realloc(vals, i*vps) из GDB и получил сообщение об ошибке: «Несоответствие, обнаруженное ld.so: dl-minimal.c: 138: realloc: Assertion `ptr == alloc_last_block' failed!»
Кто-нибудь знает, что происходит?