每个方法调用上都覆盖了本地变量指针
Local variable pointer overwritten on each method call
我目前正在读一本关于数据结构的书,并在一旁学习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);
}
请注意,这段代码设计得并不完全好(有些东西应该是私有的,应该避免使用using namespace std
)。我熟悉python,所以这个指针的东西有点让人不知所措。提前感谢您的帮助!
Node<T>* newNode_ptr = new Node<T>(newVal);
这是两者中比较正确的方式。newNde_ptr
的地址不同是正常的,这是你想要的。每个节点都是不同的节点,两个不同的对象不能有相同的地址!没有new
的版本提供相同的地址,因为您正在堆栈上创建对象。这将不起作用,每个节点在append
函数结束时都会被销毁。如果您将append
的打印部分移动到另一个函数,您将看到异常结果(如果它没有崩溃)。由于所有指针都指向同一个地址(在您的情况下),并且在打印出地址为的值时,恰好是一个有效的节点,因此您不会看到崩溃。然而,这是一种未定义的行为,可以由于多种原因而更改。
免费存储(malloc/free的堆)和堆栈之间的区别是c++的一个基本概念。你应该在这里读一下。
我之所以看到这两个更正确的方式,是因为您仍然必须记住delete
您的节点。一个更好的方法是使用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++ - 使用变量指针调用函数
- 如何返回值为NULL的变量指针
- 在编译时以增量方式构建变量指针的向量
- C 取消实例变量指针
- 每个方法调用上都覆盖了本地变量指针
- 决定对基类的变量指针进行函数调用
- 使用 valgrind 时获得 int 变量指针的无效读取大小错误
- 变量指针的成员函数未绘制到SDL_Surface?
- 何时使用成员变量指针
- 从成员变量指针返回布尔值
- 指向C#和C++之间接口的变量指针
- c++中指向self的成员变量指针
- 为什么变量指针包含相同数据类型的地址?
- 指向用户定义类型的类的全局变量指针
- C++分配一个变量指针地址