односвязный список конструктор, деструктор и распечатка C ++ - PullRequest
0 голосов
/ 13 декабря 2018

Я новичок в изучении c ++ и в настоящее время делаю односвязный список.У меня возникли некоторые проблемы, и я очень долго думал, много искал, но до сих пор не нашел ответа на этот код, поэтому прошу помощи ...

Так что это мой связанный.h

template <class T>
class Node {
    public:
        T data;
        Node<T>* next;
};

template <class T>
class List {
    private:
        Node<T> *head;
    public:
        List() : head(NULL) {};
        ~List() {
            Node<T>* ptr, tmp;
            for(ptr = head->next; ptr == NULL; ptr = head->next) {
                delete ptr;
            }     
        }
        List(T* arr, int n_nodes) {
            head = NULL; 
            Node<T> *tmp = head;
            for(int i = 0; i < n_nodes; i++) {
                Node<T>* node = new Node<T>;
                node->data = arr[i];
                if(head == NULL) {
                    head->next = node;
                    tmp = node;
                }
                else {
                    tmp->next = node;
                    node->next = NULL;
                    tmp = node;
                }
            }
        }
        friend std::ostream& operator<<(std::ostream& out, List<T>& rhs) {                                                                                                                                 
            Node<T>* cur = rhs.head;
            out << cur;
            while(cur != NULL) {       
                if(cur->next != NULL) { 
                    out << cur->data << ", ";
                    cur = cur->next;
                }
                else
                    out << cur->data << " ";
            }
            return out;
        }
}; 

и это мой файл main.cc.

#include <iostream>
#include "linked.h"

int main() {
    int array[5] = {12, 7, 9, 21, 13};
    List<int> li(array, 5);
    std::cout << li;

    return 0;
}

Я продолжаю получать ошибку сегментации при запуске конструктора, и я не понимаю, почему.Где я делаю ошибку?Любая помощь будет оценена!

1 Ответ

0 голосов
/ 13 декабря 2018

Вы могли бы покрыть проблему указателем на указатель:

List(T* arr, int n_nodes)
{
    Node<T>** tmp = &head; // tmp *pointing* to uninitialized(!) head pointer
    for(int i = 0; i < n_nodes; i++)
    {
        Node<T>* node = new Node<T>();
        node->data = arr[i];
        // now the trick:
        *tmp = node; // !!!
        // you now have assigned the new node to whatever pointer
        // the tmp pointer points to - which initially is - guess - head...

        // but we now need to advance!
        tmp = &node->next;
    }
    // tmp now points to latestly created node's next pointer
    // (or still head, if no nodes where created because of n_nodes == 0)
    // be aware that this one still is not initialized! so:
    *tmp = nullptr;
}

Ваш деструктор тоже обязательно потерпит неудачу:

Node<T>* ptr, tmp;
for(ptr = head->next; ptr == NULL; ptr = head->next)
{
    delete ptr; // you delete ptr, but advancing (ptr = head->next)
                // is done AFTERWARDS, so you'd access already deleted memory
                // undefined behaviour
}

Кроме того, вы не удаляете головной узел!И если head равно nullptr, у вас снова неопределенное поведение.

Попробуйте это так:

while(head)
{
    Node<T>* tmp = head; // need a copy of pointer
    head = head->next;   // need to advance BEFORE deleting
    delete tmp;          // now can delete safely
}
...