我对C ++ /指针不是很熟悉,但是尝试实现单链接列表。
我只是创建一个Node
(head
)并在每次将新的Node
添加到列表中之后在head
之后添加struct Node {
int key;
Node *next;
Node() : key(-1), next(nullptr) { }
Node(int k) : key(k), next(nullptr) { }
};
void AddNode(Node *head, int key) { // Create a new node & add it after the head
Node newNode(key);
newNode.next = head->next;
head->next = &newNode;
}
void PrintNode(Node *nptr, string pre, string post) {
cout << pre << "(" << nptr << "), " << nptr->key << ", " << nptr->next << post;
}
void PrintLL(Node *nptr) {
if (nptr) {
PrintNode(nptr, "\n", "");
nptr = nptr->next;
while (nptr) {
PrintNode(nptr, " -> ", "");
nptr = nptr->next;
}
}
cout << endl;
}
int main()
{
Node n1(1); // Node(1) or head
Node *head = &n1;
AddNode(head, 2); // Node(2)
PrintLL(head); // Node(2) gets modified with this call in VS 17
AddNode(head, 3); // Node(3) turns out to be Node(2) with 3 as key in MinGW
PrintLL(head);
return 0;
}
。
Node(2)
当我在VS 2017中运行此程序时,这将引发异常。调试显示,在head
(Node(1)
)之后正确添加了PrintLL()
,但是当调用Node(2)
时key
的{{1}}被更改为从next
到NULL
的随机数&0xcccccccc
。
使用MinGW编译该程序并运行时,它会运行,但会分配Node(2)
和Node(3)
相同的内存(?),如该输出所示-
(0x71fe30), 1, 0x71fdf0 -> (0x71fdf0), 2, 0
(0x71fe30), 1, 0x71fdf0 -> (0x71fdf0), 3, 0
我不确定我缺少什么,也无法弄清楚。请帮忙。
谢谢。
答案 0 :(得分:5)
您在AddNode()
中有一个悬空参考。 Node newNode(key);
是一个局部变量,在返回AddNode()
之后不再存在。因此,head->next
指向无处。使用new
手动在堆上分配,或者最好使用std::unique_ptr
这样的智能指针。
Node
和AddNode
可能看起来像这样:
struct Node {
int key;
std::unique_ptr<Node> next;
Node(int k = -1, std::unique_ptr<Node> n = {})
: key(k), next(std::move(n))
{ }
};
Node& AddNode(Node& head, int key)
{
head.next = std::make_unique<Node>(key, std::move(head.next));
return *head.next;
}
编辑。请注意以下有关此方法潜在陷阱的第一条评论-在自动列表重新分配期间出现堆栈溢出。