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?

È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top