实现模板化的单向链表时遇到问题

Trouble implementing a templated singly linked list

本文关键字:链表 遇到 问题 实现      更新时间:2023-10-16

我正在尝试实现一个模板化的单链表,我对C++相当陌生

#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();
}

我无法让这个工作。以某种方式使用 for 循环迭代列表不起作用。它总是导致关于指向0xCCCCCCD0的指针的读取访问冲突异常,我不知道如何解决这个问题。

您的add函数不正确

Node<Data> new_node(d, head_ptr);

add 中创建新函数 local Node。 然后,将head设置为该局部变量的地址。 当函数结束时,所有局部变量都将被销毁,因此现在head指向不再存在的对象。

要解决此问题,您需要使用 new 关键字创建一个动态对象,该对象将在函数结束后继续存在。

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

这样做的缺点是您需要记住在列表析构函数中创建的所有节点上调用delete

代码中还有一些其他错误。 您从未在构造函数中设置max_size因此除了给它一个值之外使用它根本不是未定义的行为,因为我们不知道它的值是什么。 在将节点添加到列表中时,也绝不会增加列表的大小。