J'écris une fonction en C qui accepte une liste chaînée et un prédicat et retourne un tableau contenant toutes les valeurs de la liste chaînée satisfaisant cette condition. Voici la fonction:C Erreur Realloc - "Assertion` ptr == alloc_last_block 'a échoué! "
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;
}
je suis passé un prédicat qui retourne toujours 1 (à savoir get_all_that est essentiellement to_array), et je me fais une erreur à la ligne à l'itération étoilée où i = 4. L'erreur sur le backtrace (qui a été automatiquement imprimé à partir d'un SIGABRT) est "*** glibc détecté *** ~/list/test: realloc(): invalide taille suivante: 0x0804c0e8 ***"
J'ai ouvert GDB lui disant de casser à droite avant d'appeler realloc quand i = 4. J'ai ensuite essayé d'appeler realloc (vals, i * vps) manuellement à partir de GDB et j'ai reçu le message d'erreur: "Incohérence détectée par ld.so: dl-minimal.c: 138: realloc: Assertion` ptr == alloc_last_block 'a échoué! "
Quelqu'un sait ce qu'il se passe?
C'est fait. Bonne prise. Pourquoi les moulages ne sont-ils pas nuls ** nécessaires? – Nick
@Nick: Parce que 'void *' est implicitement converti vers et à partir de tout autre type de pointeur (en C, pas en C++). – caf
Le point entier des pointeurs 'void' (que' malloc' et 'realloc' retournent) est qu'ils se convertissent automatiquement en n'importe quel type de pointeur (non-function-). Pourquoi c'est une mauvaise idée (en termes de style, maintenabilité, et les erreurs de masquage) est un sujet sur lequel vous pouvez faire une recherche. –