代码在不同平台上展示不同的行为,请求解释

时间:2016-06-09 13:14:20

标签: c++ c++11

在尝试回答stackexchange上的问题时,我试图查看这段代码:

#include <iostream>


using namespace std;

struct Node {
    int key;
    Node *leftnode;
    Node *rightnode;
    string value;
    Node(int tkey, const std::string& tvalue) : leftnode(nullptr), rightnode(nullptr), key(tkey), value(tvalue) {}
};

Node root_node(1, "Node #1"); // Binary search tree
string inline query_bst(const int key) {
    Node *cur_node = &root_node;
    while (cur_node != NULL) {
        if (key == cur_node->key) {
            return cur_node->value;
        }
        if (key < cur_node->key) { /* value already returned, no need for else */
            cur_node = cur_node->leftnode;
        } else {
            cur_node = cur_node->rightnode;
        }
    }
    return ""; // Return empty string if not found
}

void inline insert_bst(int key, string value) {
    Node *cur_node;
    Node *next_node = &root_node;
    // Search through bst for key
    while (next_node != NULL) {
        cur_node = next_node;
        if (key < cur_node->key) {
            next_node = cur_node->leftnode;
        } else {
            next_node = cur_node->rightnode;
        }
    }
    Node new_node(key, value);
    next_node = &new_node;
    if (key < cur_node->key) {
        cur_node->leftnode = next_node;
    } else {
        cur_node->rightnode = next_node;
    }
}

int main() {
    root_node.key = 1;
    insert_bst(2, "Node #3");
    insert_bst(3, "Node #4");

    cout << query_bst(3) << '\n' << query_bst(4);
}

对我来说,这个程序编译,但崩溃了。我搜索了这个的原因,并推断(希望是正确的)在函数“insert_bst()”中创建一个名为“new_node”的变量,然后为该变量的地址指定一个指针。但是,new_node var具有自动持续时间,因此在函数执行结束时会被销毁。因此,在第二次调用insert_bst()期间,当程序尝试访问插入节点的键/值时,将重新获取垃圾值(这是我使用调试器确认的),这会破坏程序。 那么为什么这段代码可以在其他平台上正常工作呢?

我的测试是在Windows 7 x64上,在Code :: Blocks 16.01和CLion上使用g ++完成的。

代码工作的平台:Mac OS X Yosemite Clion,也是g ++

1 个答案:

答案 0 :(得分:2)

正如您所推断的那样,该函数正在创建一个本地对象并将其添加到BST。当函数返回时本地对象被销毁时,我们现在有一个悬空指针并使用它是未定义的行为。

由于未定义的行为意味着程序的行为未定义。它可能会运行,崩溃,变得自我意识并将自己命名为天网或其他任何东西。

正如MikeCAT指出的那样,我们可以通过使用new来使节点持久化并摆脱悬空指针问题来摆脱这种未定义的行为。