c++ - 单链表c++构造函数、析构函数和打印

标签 c++ list linked-list singly-linked-list

本人初学c++,目前正在做单向链表。我遇到了一些问题,我想了很长时间,搜索了很多但仍然没有找到这段代码的答案,所以我请求帮助..

所以这是我的 linked.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;
}

我在运行构造函数时一直出现段错误,但我不明白为什么。我在哪里犯了错误?任何帮助将不胜感激!

最佳答案

你可以用指向指针的指针来解决这个问题:

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
}

关于c++ - 单链表c++构造函数、析构函数和打印,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53764847/

相关文章:

java - 安卓 native : cannot allocate large memory under native layer

Python 如何检测我是否迭代了列表中的新项目?

C EXC_BAD_ACCESS 链表崩溃

c - 有没有一种方法可以使用链表来简化我的蒙特卡洛代码

c++ - 检查内存泄漏

c++ - boost静态库编译时链接错误 "undefined reference"

python - 将输出包含在列表中

来自读者的 Python 列表

java - 完成链表排序后,我不确定如何跳出循环

c++ - 关于 C++ 自动完成的 Eclipse CDT 文档