Bonjour
Arf, malheureusement dans ce cas là, son propre avis n'a que peu de valeur. Surtout face à un crash mémoire qui, lui, est la preuve concrète que justement ce n'est pas le cas (et c'est une chance car bien souvent le code "semble" fonctionner laissant alors l'erreur bien cachée et invisible prête à ressortir à un autre moment bien souvent bien pire)
Ce qui est dommage, c'est que dans tout ce code il manque la fonction destroy_node() (probablement celle qui appelle le free()) et qui était donc la plus importante.
Ce que je peux dire de ce que je vois
- tu fais un malloc pour le node, et sans même vérifier le résultat de cette allocation (donc qui peut échouer) tu vas remplir node->data. Et enfin tu vérifies la réussite de l'allocation de node (tu peux te dire que mieux vaut tard mais en fait pas en C)
- ton test se fait via assert() donc au cas où c'est pas vérifié tu crashes tout ton code direct. Une gestion d'erreur c'est une gestion d'erreur. Un truc pensé. Si la fonction est en échec, alors elle nettoie proprement les ressources allouées avant l'échec puis elle renvoie une valeur spéciale à l'appelant. Qui lui détectant alors son propre échec fera de même et ainsi de suite jusqu'au main() qui, seul, a le droit de quitter le programme
- si node->data n'a pas été alloué, alors l'initialisation de right et left passe à la trappe. Pourtant me semble que ces deux éléments n'ont absolument rien à voir avec data...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Node create_node(const void *data, size_t data_size) {
Node node = malloc(sizeof(Node));
if (node == NULL) return NULL;
node->data = malloc(data_size);
if (node->data == NULL) {
free(node);
return NULL;
}
node->right = node->left = node->parent = NULL;
set_color(node, RED);
memcpy(node->data, data, data_size);
return node;
} |
Bon, voilà pour les choses qui auraient pu être réellement faites correctement. Ah oui un dernier truc: les globales c'est franchement le truc à éviter. Solution de facilité pour s'éviter de se prendre la tête avec les paramètres à passer aux fonctions mais dans 98% des cas générant plus de soucis au final tout en solutionnant en réalité pas grand chose.
C'est vrai que c'est une écriture assez peu usitée. Pas interdite mais bon, parfois écrire les choses individuellement ne coûte rien et si ça améliore la lisibilité... Mais à mon avis, valgrind râle parce que l'initialisation était faite dans une alternative (donc pouvait ne pas se faire).
Partager