2016-04-27 10 views
1

Ich versuche, eine Templat einzeln verknüpfte Liste zu implementieren, und ich bin ziemlich neu in C++Ärger Implementierung eine Templat einfach verkettete Liste

#include <iostream> 
#include <string> 

#define NEWL "\n" 
#define PRINT(s) std::cout << s 
#define PRINTL(s) std::cout << s << NEWL 
#define PRINTERR(e) std::cerr << e << NEWL 

////// Class for a Node 
template<class Data> class Node { 
    Node<Data>* next_ptr; 
    Data   data; 
public: 
    Node(Node<Data>* nxt_ptr)   :next_ptr(nxt_ptr) {}; 
    Node(Data d, Node<Data>* nxt_ptr) :data(d), next_ptr(nxt_ptr) {}; 

    Node<Data>* get_next() { return next_ptr; } 
    Data&  get_data() { return data; } 

    friend std::ostream& operator<<(std::ostream& out, const Node<Data>& node) { 
     out << node.data; 
     return out; 
    }; 
}; 


////// Class for a SinglyLinkedList 
template<class Data> class SLinkedList { 
    Node<Data>* head_ptr; 
    int   max_size; 

public: 
    SLinkedList() : head_ptr(nullptr) {}; 

    bool is_empty() { 

     return head_ptr == nullptr; 

    }; 
    bool is_full() { 

     return get_size() == max_size; 

    }; 
    int get_size() { 

     if (is_empty()) { 
      return 0; 
     } 
     int count = 0; 
     for (Node<Data>* it_ptr = head_ptr; it_ptr != nullptr; it_ptr = it_ptr->get_next()) { 
      count++; 
     } 
     return count; 

    }; 
    void add(Data d) { 
     if (is_full()) { 
      throw std::exception("List is full!"); 
     } 
     Node<Data> new_node(d, head_ptr); 
     head_ptr = &new_node; 
    }; 
    void print_content() { 
     int count = 1; 
     PRINTL("This list contains:"); 
     for (Node<Data>* it_ptr = head_ptr; it_ptr != nullptr; it_ptr = it_ptr->get_next()) { 
      PRINTL("\t["<< count << "]" << " at " << it_ptr << " : " << *it_ptr); 
      count++; 
     } 
    } 
}; 

////// Main function 
int main() 
{ 

    SLinkedList<int> sll; 
    sll.add(42); 
    sll.print_content(); 

} 

ich dies nicht zur Arbeit kommen kann. Irgendwie funktioniert das Iterieren der Liste mit for-Schleifen nicht. Es führt immer zu einer Lesezugriffsverletzungsausnahme über einen Zeiger auf 0xCCCCCCD0 und ich habe keine Idee, wie das behoben werden kann.

+1

Ich möchte erwähnen (obwohl es bereits eine gute Antwort gibt), dass '0xCCCCCCD0' nah an einem magischen Debug-Code ist. Es sieht so aus, als würde Ihnen die Microsoft Debug Runtime mitteilen, dass Sie nicht initialisierten Stackspeicher verwenden: http://stackoverflow.com/a/127404/487892 Das Erkennen dieser magischen Debugcodes kann Ihnen in Zukunft helfen. – drescherjm

Antwort

2

Ihre add Funktion ist falsch

Node<Data> new_node(d, head_ptr); 

eine neue Funktion lokale Node in add schafft. Dann setzen Sie head auf die Adresse dieser lokalen Variable. Wenn die Funktion endet, sind alle lokalen Variablen zerstört, so dass nun head auf ein Objekt zeigt, das nicht mehr existiert.

Um das zu beheben, müssen Sie das Schlüsselwort new verwenden, um ein dynamisches Objekt zu erstellen, das nach dem Ende der Funktion weiterlebt.

Node<Data>* new_node = new Node(d, head_ptr); 
head_ptr = new_node; 

Die Kehrseite dabei ist, Sie delete auf allen Knoten in der Liste destructor erstellt erinnern müssen, nennen.

Sie haben auch einige andere Fehler in Ihrem Code. Sie setzen nie max_size in Ihrem Konstruktor, so dass es überhaupt verwendet wird, außer dass es einen Wert hat undefiniertes Verhalten ist, da wir keine Ahnung haben, welchen Wert es haben wird. Sie erhöhen die Größe der Liste auch nie, wenn Sie Knoten zur Liste hinzufügen.

+0

Das war's, danke! – blubbi

Verwandte Themen