数组指针中的所有值在函数调用时被修改

All values in array pointer being modified upon function call

提问人:M K 提问时间:10/27/2023 最后编辑:M K 更新时间:10/27/2023 访问量:60

问:

因此,我有这个基于链表数据结构的可哈希数据结构:

//linked list node  

struct node{
    char* symbol;
    int weight;
    struct node* succ;
};
typedef struct node node;

//linked list 

struct linkedList{
    node* head;
};
typedef struct linkedList linkedList;

//hashtable  

struct hashTable{
    linkedList* cells;
    int capacity;
};
typedef struct hashTable hashTable;

我正在尝试为哈希表实现插入函数。目前,该函数(以及它调用的函数,insertion_linkedList)的代码如下:

//linked list insertion

void insertion_linkedList(linkedList* l, node n){
    node** p = &l->head; 
    if (*p == NULL){
        *p = &n;
    }
    else{
        while ((*p)->succ != NULL){
            *p = (*p)->succ;
        }
    }
    (*p)->succ = &n;
    return;
}


//hashtable insertion 

void insertion_hashTable(hashTable h, char* s, int n){
    node ins = {.symbol = s, .weight = n, .succ = NULL};
    insertion_linkedList(&h.cells[hashFunction(s, h.capacity)], ins);
}

出于某种我不明白的原因,每当我尝试将新节点插入到哈希表数据结构中时,所有先前插入的值也会被修改为与最近添加的节点对应的值。看:

int main(){
    int cap = 100;
    hashTable h = creation_hashTable(cap);

    insertion_hashTable(h,"b",4);
    insertion_hashTable(h,"a",1);
    insertion_hashTable(h, "c", 2);

    printf("%i\n", h.cells[hashFunction("b",h.capacity)].head->weight);
    // !! returns 2 and not 4 !!

    exit(0);
}

老实说,我真的不明白这里发生了什么(我猜这与残余指针值有关?任何帮助将不胜感激。提前致谢。

数组 C 列表 指针 哈希表

评论


答:

1赞 Oka 10/27/2023 #1

*p = &n;

(*p)->succ = &n;

&n是指向局部变量(函数参数)的指针 - 具有自动存储持续时间的对象。一旦函数返回,此指针就无效,此时取消引用它会调用未定义的行为

另请参见:悬空指针

为了使链表以任何有意义的方式扩展,您需要使用动态内存分配来延长放置在列表/表中的对象的生命周期。

一个粗略的例子是:

void insertion_linkedList(linkedList *l, node n) 
{                                                                                  
    node *new = malloc(sizeof *new);
    /* byte-wise copy of `n` to the memory pointed at by `new` */
    *new = n;
        
    if (!l->head)
        l->head = new;
    else {                             
        node *current = l->head;              
                                              
        while (current->succ)                 
            current = current->succ;                                               
                                              
        current->succ = new;
    }
}

这些指向动态分配对象的指针稍后必须传递给 free