C Realloc errore - “Asserzione` PTR == alloc_last_block' fallito!”
-
27-09-2019 - |
Domanda
Sto scrivendo una funzione in C che prende in una lista collegata e un predicato e restituisce un array contenente tutti i valori della lista collegata soddisfare questa condizione. Ecco la funzione:
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;
}
Ho passato in un predicato che restituisce 1 (vale a dire sempre get_all_that è fondamentalmente to_array), e sto ottenendo un errore alla linea stellato sulla iterazione in cui i = 4. L'errore sul backtrace (che è stata automaticamente stampato da un SIGABRT) è "*** glibc rilevato *** ~ / list / test: realloc (): non valida seguente formato: 0x0804c0e8 ***"
Ho aperto GDB dicendogli di rompere a destra prima di chiamare realloc quando i = 4. Allora ho provato a chiamare realloc (vals, i * VPS) manualmente da GDB ed ho ottenuto il messaggio di errore: "Incoerenza rilevata da ld.so: dl-minimal.c: 138: realloc: Asserzione` PTR == alloc_last_block' fallito! "
Qualcuno sa che cosa sta succedendo?
Soluzione
Il realloc
è l'attribuzione di un troppo pochi elementi. Provare a sostituire i
da i+1
. Si dovrebbe anche controllare per il fallimento di realloc
prima di sostituire il puntatore passato a esso, poiché altrimenti si otterrà una perdita di memoria (per non parlare di incidente in quanto non si riesce a verificare la presenza di NULL
) in caso di fallimento, e la rimozione dei calchi inutili e brutte dalla valore di ritorno di realloc
sarebbe troppo bello.
Altri suggerimenti
E la tua prima realloc
chiama la lunghezza con 0, che è un free
. Quindi il consiglio di mettere i+1
è doppiamente importante.