struct对象的指针成员在传递给函数时被修改

Pal*_*shV 1 c++

我对C++ /指针并不熟悉,但试图实现单链表.

我只是创建一个Node(head)并Nodehead每次将新的一个添加到列表后添加.

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;
}
Run Code Online (Sandbox Code Playgroud)

当我在VS 2017中运行此程序时,这会引发异常.调试表明,Node(2)被后正确添加head(Node(1)),但是当PrintLL()被调用Node(2)key得到改变一些随机数nextNULL0xcccccccc.

当这个程序使用MinGW编译并运行时,它运行但是分配Node(2)Node(3)相同的内存(?),因为此输出建议 -

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

(0x71fe30), 1, 0x71fdf0 -> (0x71fdf0), 3, 0
Run Code Online (Sandbox Code Playgroud)

我不确定我错过了什么,也无法弄明白.请帮忙.

谢谢.

Evg*_*Evg 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;
}
Run Code Online (Sandbox Code Playgroud)

编辑.请注意以下关于此方法潜在缺陷的第一条评论 - 自动列表释放期间的堆栈溢出.

  • 碰到了答案.需要注意的是:在使用智能指针链接潜在的深层容器时要小心.在销毁链中,可能容纳*数千个节点的链表很容易通过激活堆栈上限/下限.有一些简单的所有权传递迭代算法可以解决这个问题. (5认同)