传递给函数时,结构对象的指针成员将被修改

时间:2018-08-16 15:44:01

标签: c++

我对C ++ /指针不是很熟悉,但是尝试实现单链接列表。

我只是创建一个Nodehead)并在每次将新的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中运行此程序时,这将引发异常。调试显示,在headNode(1))之后正确添加了PrintLL(),但是当调用Node(2)key的{​​{1}}被更改为从nextNULL的随机数&0xcccccccc

使用MinGW编译该程序并运行时,它会运行,但会分配Node(2)Node(3)相同的内存(?),如该输出所示-

(0x71fe30), 1, 0x71fdf0 -> (0x71fdf0), 2, 0

(0x71fe30), 1, 0x71fdf0 -> (0x71fdf0), 3, 0

我不确定我缺少什么,也无法弄清楚。请帮忙。

谢谢。

1 个答案:

答案 0 :(得分:5)

您在AddNode()中有一个悬空参考。 Node newNode(key);是一个局部变量,在返回AddNode()之后不再存在。因此,head->next指向无处。使用new手动在堆上分配,或者最好使用std::unique_ptr这样的智能指针。

NodeAddNode可能看起来像这样:

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;
}

编辑。请注意以下有关此方法潜在陷阱的第一条评论-在自动列表重新分配期间出现堆栈溢出。