c++ - 在每次方法调用时覆盖局部变量指针

标签 c++ pointers linked-list

我目前正在阅读一本关于数据结构的书,同时也在学习 C++。我正在尝试实现一个简单的链表。下面是一个列表的一些代码,最多可以包含两个元素(为了隔离我的问题)。 出问题的是指向列表中下一个节点的指针声明。当我创建一个新的 Node 实例并创建一个指向它的指针时,该指针在每次方法调用时都保持不变,因此列表中的所有元素都指向同一个节点。但是,如果我直接创建一个指针,一切都会按预期进行。

我猜测我对指针、引用和 new 关键字有一些根本性的误解。

请随意运行下面的代码。工作代码已被注释掉。

#include <iostream>
using namespace std;

template <typename T> class Node {
public:
    Node(T nvalue) {
        this->value = nvalue;
        this->next = NULL;
    }
    T value;
    Node *next;
};

template <typename T> class LinkedList {
    public:
        Node<T> *head;
        LinkedList() {
            this->head = NULL;
        }
        void append(T newVal) {
            // Correct
            // Node<T>* newNode_ptr = new Node<T>(newVal); // newNode_ptr is different on each call
            // Incorrect!?
            Node<T> newNode = Node<T>(newVal);
            Node<T> * newNode_ptr = &newNode; // newNode_ptr is the same on each call
            cout << "New Node Address: " << newNode_ptr << endl; 
            if (!(this->head)) {
                this->head = newNode_ptr;
                cout << "Value 0: " << this->head->value << endl;
            } else {
                this->head->next = newNode_ptr;
                cout << "Value 0: " << this->head->value << endl;
                cout << "Value 1: " << this->head->next->value << endl;
            }
        }
};

int main() {
    LinkedList<int> list = LinkedList<int>();
    list.append(21);
    cout << "..." << endl;
    list.append(42);
}

请注意,这段代码设计得并不好(有些东西应该是私有(private)的,应该避免using namespace std)。我熟悉 python,所以这个指针的东西有点让人不知所措。提前感谢您的帮助!

最佳答案

 Node<T>* newNode_ptr = new Node<T>(newVal);

这是两者中比较正确的一种。 newNde_ptr的地址不同是正常的,这就是你想要的。每个节点都是一个不同的节点,两个不同的对象不能有相同的地址!没有 new 的版本给出了相同的地址,因为您是在堆栈 上创建对象。这是行不通的,每个节点都在 append 函数结束时被销毁。如果将 append 的打印部分移动到另一个函数,您将看到异常结果(如果它没有崩溃)。由于您所有的指针都指向相同的地址(在您的情况下),并且在您打印出地址 just so happens 的值是有效节点时,您不会看到崩溃。但是,这是未定义的行为,可能会因多种原因而改变。

自由存储(malloc/free 的堆)和堆栈之间的区别是 c++ 的一个基本概念。你应该读一读 here .

我看到两者中更正确的方法的原因是您仍然必须记住删除您的节点。更好的方法是使用 std::unique_ptr而不是原始指针,以避免使用原始指针所导致的(以及其他)错误。

// Node * next; becomes
std::unique_ptr<Node> next;

// Node<T> newNode = Node<T>(newVal); becomes
newNode = std::make_unique<T>(newVal);

关于c++ - 在每次方法调用时覆盖局部变量指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41555334/

相关文章:

c++ - 为什么在C++中调用库(建库成功)会出现链接错误

c++ - 只有变量名的语句

c++ - C++ 中的 "free(): invalid next size (fast)"

c++ - 将 std::string 转换为 char * 替代

c++ - 为什么用 double& 初始化对象方法不起作用?

java LinkedList 的 LinkedList.isEmpty() 方法无法正常工作?

java - 有效地从 Java LinkedList 中删除一个项目

c++ - 类成员引用变量有内置的 "const-correctness"吗?

c - 访问嵌套结构成员的多种方式

c++ - 摆脱 “Undeclared identifier”错误