c - 指针处的值仅在使用时才会更新

标签 c pointers gcc

刚刚注意到一些奇怪的行为,有人可以解释并告诉我我做错了什么吗?

我想使用 C 语言使用链表指针数组来实现哈希集,但是,当我添加链表节点时,只有先将其打印出来,数据值才会更新。

这是我的代码:

#include <stdio.h>
#define print(ref) printf(#ref" = %d\n",ref);
#define HASH_MODULE 13

typedef struct listNode{
    int data;
    struct listNode*next;
}listNode;

void addToSet(int,listNode**);
int hashCode(int);


int main(){
    listNode*linkedListHashset[HASH_MODULE];

    addToSet(10,linkedListHashset);
    print(linkedListHashset[10]->data);

    return 0;
}

void addToSet(int value, listNode**set){
    int bucket = hashCode(value);
    print(bucket);
    listNode newNode = {value};
    newNode.next = set[bucket];
    set[bucket] = &newNode;
    //print(set[bucket]->data);
}

int hashCode(int value){
    return value%HASH_MODULE;
}

你可以看到有一个注释掉的行,如果我像这样编译它,该值将不会被存储,给出这个输出(这不是我所期望的):

bucket = 10
linkedListHashset[10]->data = 0

但是,当我在输出中包含注释掉的行时,它确实反射(reflect)了所需的更新,这里指针处的数据的行为符合我的预期:

bucket = 10
set[bucket]->data = 10
linkedListHashset[10]->data = 10

我认为这可能是编译器工件或其他东西,我通过以下方式进行编译:

$gcc -Wall -Werror -O -o  source.c

因此没有警告,一切似乎都井然有序。你怎么认为?我错过了什么?

最佳答案

addToSet 中,您在堆栈上声明 newNode,然后将其地址存储在 set[bucket] 中并返回。然后它变成一个悬空指针,当您在 main 中取消引用它时,会导致未定义的行为。

关于c - 指针处的值仅在使用时才会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52601328/

相关文章:

c - 英特尔 C++ - 优化器消息

c - Ncurses WINDOW 无法正确刷新

c++ - C 编译器无法创建可执行文件,OpenSolaris Erlang/OTP ./configure 错误

c - 函数参数中的*和&有什么区别?

c - 使用 Linux AIO,能够执行 IO,但也会将垃圾写入文件

c - LD_PRELOADing malloc 和 free

c - clang 和 gcc 之间的 float 操作结果不一致

c - 程序循环两次(打印语句两次)

c - 是否可以通过循环设置分配的内存的值?

c - 它在 GCC 源代码的哪个位置编译成不同的汇编语言?