Des problèmes pour créer et itérer à travers une liste chaînée?

Lorsque j’exécute le programme ci-dessous, il affiche “un: 1” au lieu de “un: 1, deux: 2”, comme je m’y attendais. Quelqu’un sait ce qui se passe ici? J’essaie de créer une fonction qui me permettra de créer autant de listes chaînées que possible au lieu de simplement déclarer des têtes globales.

struct Node { int value; char label[10]; node *next; }; typedef struct Node node; int add(int data, char name[], node *head) { node *newNode = (node *)malloc(sizeof(node)); if (newNode != NULL) { newNode->value = data; strcpy(newNode->label, name); newNode->next = head; head = newNode; } } node* createNewLinkedList(int d, char *name) { node *newNode = (node *)malloc(sizeof(node)); newNode->value = d; strcpy(newNode->label, name); newNode->next = NULL; return newNode; } int main() { node *head1 = createNewLinkedList(1, "one"); add(2, "two", head1); iterate(head1); } 

Vous passez un pointeur sur le nœud. Comme tous les parameters en C, il est passé par valeur, donc head = newNode; n’a aucun effet sur l’appelant.

Vous devez modifier la signature pour accepter le node **head et append un niveau d’indirection afin que les modifications apscopes soient reflétées dans l’ main .

 int add(int data, char name[], node **head) { node *newNode = (node *)malloc(sizeof(node)); if (newNode != NULL) { newNode->value = data; strcpy(newNode->label, name); newNode->next = *head; *head = newNode; } } 

Bien sûr, vous devrez passer &head1 à la méthode add(2, "two", &head1); : add(2, "two", &head1);

PS Puisque vous ajoutez {2, “deux”} au début de la liste, votre sortie sera “deux: 2, une: 1”.

head = newNode; ne fera pas ce que vous attendez.

la tête est passe-par-valeur ici. Penses-y.

De add , vous ne connectez pas le nouveau nœud à la fin de votre liste, vous créez simplement un nouveau nœud complètement déconnecté de votre liste actuelle. De plus, vous ne retournez pas d’ int de cette fonction conformément à la signature de la fonction.

Je soupçonne que vous souhaitez définir le nouveau nœud comme tête avec cette ligne:

 head = newNode; 

Si tel est le cas, changez head en type node** et faites *head = newNode , sinon vous modifiez simplement une variable locale pour qu’elle pointe vers newNode , et non le pointeur head1 réel transmis par main . En main vous passez ensuite &head1 à add .

EDIT: Ce qui serait probablement plus logique, c’est d’avoir head->next = newNode; , ou pour parcourir la fin de la liste et définir la valeur next du nœud qui pointe vers NULL sur newNode . c’est à dire.

 node *lastNode = head; while (lastNode->next != NULL) /* get to the last node in the list */ lastNode = lastNode->next; lastNode->next = newNode; /* add newNode to the end of the list */ 

newNode->next = NULL également newNode->next = NULL au lieu de newNode->next = head . La sortie sera désormais "one : 1, two: 2" , au lieu de "two: 2, one : 1" qui se serait passé si vous aviez ajouté le nouveau newNode à la tête.

Sans voir votre function head1 le problème est que head1 pointe vers le dernier élément de la liste, pas le premier. Vous vouliez probablement dire que la dernière ligne de la fonction add était:

 return head; 

et 2ème ligne de votre programme pour être:

 head1 = add(2, "two", head1); 

Mais cela vous donnera probablement toujours votre sortie dans le mauvais ordre, car votre fonction add ajoute le nouvel élément au début de la liste, pas la fin.

Pour comprendre le problème en détail, consultez The C Programming Language de Kernighan & Ritchie – Introduction (chapitre 1.7 / 1.8) et Fonctions et structure du programme (chapitre 4).

Astuce: pass-by-value et pass-by-address

 int main() { ... add(2, "two", &head1); ... } 

OTOH, vous devez valider l’adresse de retour de malloc avant de la dé-référencer (dans createNewLinkedList ).