代码之家  ›  专栏  ›  技术社区  ›  NoobProgrammer

在C中:创建了一个节点,忘记返回指向该节点的指针,但代码仍然像我返回的一样运行

  •  1
  • NoobProgrammer  · 技术社区  · 11 月前

    我在C中实现了一些有趣的数据结构,并将其速度与我实现的其他数据结构进行了比较。这是一个封闭寻址哈希表。

    这是我用来创建节点的代码

    hashNode *createNewNode(int data) {
        hashNode *node = calloc(1, sizeof(hashNode));
        node->data.key = data;
        node->isSet = true;
        node->next = NULL;
    }
    

    这是我想要计时的功能。

    for (int i = 0; i < 5; i++) {
        hashNode *node = createNewNode(arr[i]);
        InsertNode(node, map);
    }
    

    (arr只是被打乱的前5000个数字) 正如您可能已经注意到的那样,创建节点的函数没有返回值,尽管如此,节点还是正确初始化了,并且插入了表中应该包含的所有数字,而且只有这些数字。这怎么会发生?

    这个gimmik只在VS代码中工作,我尝试在Visual Studio中运行它,但它(正确地)没有初始化节点。有人知道发生了什么吗?

    编辑:好吧,我可能没有正确表达自己,对不起。我的问题是,它是如何工作的?我知道这是一种未定义的行为,但它看起来不像是应该工作的东西,但它在5000次中正确工作了5000次,即使我在这里和那里打印一些,它也能正常工作

    1 回复  |  直到 11 月前
        1
  •  2
  •   dbush    11 月前

    如果未能从定义为返回值的函数中返回值,然后尝试使用该函数的返回值,则会触发 undefined behavior 在您的代码中。

    对于未定义的行为,无法保证你的代码会做什么。它可能会崩溃,可能会输出奇怪的结果,或者可能(在你的情况下)看起来工作正常。

    此外,对代码进行看似无关的更改(例如添加未使用的局部变量或调用 printf 用于调试)可以改变未定义行为的表现方式。使用不同的优化设置或使用不同的编译器进行编译也会产生差异。

    什么 可以 在你的情况下发生的是 node 可能位于寄存器中,而该寄存器恰好是函数返回值所在的寄存器。但同样,它以这种方式工作本质上是运气。