2016-07-17 9 views
1

Ich lerne Zeiger in c und schrieb ein Programm, das Elemente in verknüpfte Liste einfügt und sie am Ende druckt.Adresse eines Knotens in der verknüpften Liste ändert sich automatisch in c

// this is exercise 2 in chapter 11 on pointers 
#include <stdio.h> 
#include <stdbool.h> 

typedef struct node 
{ 
    int value; 
    struct node * next; 
}node; 

/** 
Insert into linked list 
**/ 

bool insert(node * list, int n); 

void printList(node *startNode); 

int main(void) 
{ 
    node n1,n2; 
    n1.value = 0; 
    n2.value = 1; 
    n1.next = &n2; 
    n2.next = NULL; 
    // insert 2 into list 
    insert(&n1, 2); 
    // print the updated list 
    printList(&n1); 
    printf("Program Executed Successfully \n"); 
    return 0; 
} 

bool insert(node * list, int n) 
{ 
    while(list->next != NULL) 
    { 
    if (list->value < n) 
    { 
     list = list->next; 
    } 
    else 
    { 
     node tempNode; 
     tempNode.value = n; 
     tempNode.next = list->next; 
     list->next = &tempNode ; 
     return true; 
    } 
    } 
    node tempNode; 
    tempNode.value = n; 
    tempNode.next = list->next; 
    list->next = &tempNode ; 

    return false; 
} 

void printList(node * startNode) 
{ 
    while(startNode->next != NULL) 
    { 
    printf("%i\n", startNode->value); 
    startNode = startNode->next; 
    } 
} 

Einfügung scheint in Ordnung zu sein. Ich habe zunächst zwei Knoten und dann habe ich einen mehr mit einem Wert von 2 hinzugefügt, aber wenn ich drucke, druckt es nur die ersten zwei Elemente korrekt.

verwendet I GDB Debugger und versucht, das Problem auftritt, zu verfolgen, wo ich sah, dass, wenn es Drucker erste und zweite Knoten hat, ist die Adresse des dritten Knotens automatisch

0x7ffff7dea560 < _dl_fini>

zu

geändert

vor zu Beginn der Druckfunktion war es

0x7ffffe018

und die Ausgabe des vollständigen Programms ist

-777224576

-443987883

Segmentation fault

Antwort

2

Die insert Funktion sieht einfach falsch, aber die schlimmsten Übeltäter sind diese Zeilen aus der Funktion:

else 
{ 
    node tempNode; 
    ... 
    list->next = &tempNode ; 
} 

Hier deklarieren Sie eine lokale Variable `tempnode und einen Zeiger darauf in der Liste speichern . Die Variable wird außerhalb des Gültigkeitsbereichs liegen und aufhören zu existieren, sobald die schließende geschweifte Klammer erreicht ist, was einen Streuzeiger zurücklässt. Der Versuch, den Streuzeiger zu dereferenzieren, führt zu undefiniertem Verhalten.

Ein wenig weiter unten machen Sie denselben Fehler noch einmal und speichern einen Zeiger auf eine lokale Variable.

+0

für 'Streuzeiger'. Das wusste ich vorher nicht. Danke für das neue Konzept. –

+0

Ich möchte nicht jedes Mal einen neuen Knoten außerhalb der Funktion übergeben, um einen neuen Knoten hinzuzufügen. Ich möchte nur den Wert des einzufügenden Knotens angeben. Kannst du mir eine Idee geben? 'malloc' würde funktionieren? –

+0

@GulluButt Die Verwendung von 'malloc' würde definitiv funktionieren, aber dann können Sie keine Teile Ihrer Liste auf dem Stapel in der' main' Funktion erstellen, wie Sie es gerade tun, Sie müssen * alle * Knoten dynamisch erstellen. Vergessen Sie auch nicht, die Knoten zu "befreien", sobald Sie damit fertig sind. –

Verwandte Themen