Klasse: Einfach verkettete Liste mit Pointern



  • Hallo,

    ich habe ursprünglich Delphi und Java gelernt und bemühe mich nun gerade um C++, da ich beruflich eine Anwendung in dieser Sprache entwickeln muss. Als Ansatz in meine Entwicklung habe ich versucht, eine einfach verkettete Liste in eine Klasse abzukapseln, die nur einfachste Funktionen beherrscht.

    Beim Ausführen des folgenden Quelltextes (der immerhin sauber kompiliert) erhalte ich jedoch immer die Nachricht "Segmentation fault". Ich habe jedoch auf Grund der Beschränktheit dieses Laufzeitfehlers noch keine Ahnung, woran es liegt und wie ich es beheben kann.

    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    
    // Structure of a single listnode
    struct node {
    	node* next;
    	int value;
    };
    
    // Declaration of the class List
    class List {
    	public:
    		void init();
    		// Creates a new, empty list
    
    		void reset();
    		// Sets current to the beginning of the list
    
    		bool advance();
    		// Moves current to the next listnode
    		// If possible true, else false
    
    		void append(int);
    		// Creates a new listnode at the end of the
    		// current list with a certain value
    
    		int elem();
    		// Returns the value of current listnode
    	private:
    		node *dummy,*current;
    };
    
    // Implementation of the class List
    void List::init() {
    	// Sets dummy = current = NULL;
    	dummy = NULL;
    	current = NULL;
    }
    void List::reset() { current = dummy; }
    bool List::advance() {
    	// If current is not at end of list, move current to current.next
    	if(current!=NULL) {
    		current = (*current).next;
    		return true;
    	// else do nothing but return false
    	} else return false;
    }
    void List::append(int val) {
    	// Allocate enough memory to fit in a new node and save its address
    	// to the pointer aNode. Initialize aNode
    	node* aNode = (node*) malloc(sizeof(node));
    	(*aNode).value = val;
    	(*aNode).next = NULL;
    	// If there is no element yet, make the new node the first one
    	if(dummy==NULL) dummy = aNode;
    	// Else make it the last one in the existing list
    	else {
    		do{} while(advance());
    		current = aNode;
    	}
    	// Move current behind the newly created listnode
    	advance();
    }
    int List::elem() { return (*current).value; }
    
    int main() {
    	List myList;
    	myList.init();
    
    	myList.append(3); myList.append(7); myList.append(10);
    	myList.reset();
    	while(myList.advance()) cout<<myList.elem()<<endl;
    }
    

    Für Hilfe hierbei wäre ich sehr dankbar. Ich habe, um euch das Leben nicht so schwer zu machen, den Quelltext so gut wie irgendsmöglich kommentiert.

    Liebe Grüße!



  • Was passiert, wenn du Liste::elem() aufrufst und current 0 ist?

    EDIT:
    Im übrigen enthält dein Code sehr viele Schwachstellen:

    • Gib den Speicher frei (free)
    • Erwäge eher new/delete, als malloc/free
    • Benutz den Konstruktor
    • Benutz den Destruktor
    • Initialisierungsliste
    • Mach das ganze generisch (templates)
    • Mach deinen Code exception sicher


  • Danke schön, das war der springende Punkt! Zumindest war es mir anschließend klar, warum der Quelltext so nicht funktionieren kann. Der funktionierende Quelltext lautet

    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    
    // Structure of a single listnode
    struct node {
    	node* next;
    	int value;
    };
    
    // Declaration of the class List
    class List {
    	public:
    		void init();
    		// Creates a new, empty list
    
    		void reset();
    		// Sets current to the beginning of the list
    
    		bool advance();
    		// Moves current to the next listnode
    		// If possible true, else false
    
    		void append(int);
    		// Creates a new listnode at the end of the
    		// current list with a certain value
    
    		int elem();
    		// Returns the value of current listnode
    	private:
    		node* current;
    		node dummy;
    };
    
    // Implementation of the class List
    void List::init() {
    	// Sets dummy = current = NULL;
    	dummy.next = NULL;
    	reset();
    }
    void List::reset() { current = &dummy; }
    bool List::advance() {
    	// If current is not at end of list, move current to current.next
    	if((*current).next!=NULL) {
    		current = (*current).next;
    		return true;
    	// else do nothing but return false
    	} else return false;
    }
    void List::append(int val) {
    	// Allocate enough memory to fit in a new node and save its address
    	// to the pointer aNode. Initialize aNode
    	node* aNode = (node*) malloc(sizeof(node));
    	(*aNode).value = val;
    	(*aNode).next = NULL;
    	// If there is no element yet, make the new node the first one
    	if(dummy.next==NULL) dummy.next = aNode;
    	// Else make it the last one in the existing list
    	else {
    		do{} while(advance());
    		(*current).next = aNode;
    	}
    	// Move current behind the newly created listnode
    	advance();
    }
    int List::elem() { 
    	if((*current).next==NULL) return -1;
    	else return (*(*current).next).value; 
    }
    
    int main() {
    	List myList;
    	myList.init();
    
    	myList.append(3); myList.append(7); myList.append(10);
    	myList.reset();
    	do {
    		cout<<myList.elem()<<endl;
    		myList.advance();
    	}	while(myList.elem()!=-1);
    }
    

    Vielen Dank für die schnelle Hilfe!

    zum Edit:
    Benutzung von Konstruktoren/Destruktoren sowie new, delete werde ich mir schnellstens aneignen.

    Exception-Handling möchte ich lieber noch ein wenig aufschieben, bis ich mich in C++ etwas sicherer fühle.

    Danke!


Anmelden zum Antworten