首页 > 解决方案 > 在循环中初始化唯一指针(用于哈希表)

问题描述

在过去的几年里,我一直在使用字典在 Python 中进行数字运算。几年后我正在重述 C,我正在尝试使用哈希表来模仿 python 字典功能。我的哈希表工作正常,但我正在努力以编程方式在循环中添加新条目。这是我的代码:

#define TABLE_SIZE 16

typedef struct item{
    char key[64];
    int value;
    int list[5];
    struct item *next;
} item;

// Create hash table array
item *hash_table[TABLE_SIZE];

void init_hash_table(){
    for (int i = 0; i < TABLE_SIZE; i++)
        hash_table[i] = NULL;
}

int hash(char *key){
    unsigned long H = 5381;
    int c;
    while ((c = *key++))
        H = ((H << 5) + H) + c;
    H = H % TABLE_SIZE;
    int hash = (int)H;
    return hash;
}

int insert_item(item *pItem){
    if (pItem == NULL){
        printf("Invalid item");
        return -1;
    }
    else {
        int index = hash(pItem->key);
        pItem->next = hash_table[index];
        hash_table[index] = pItem;
        return index;
    }
}

void print_table(){
    printf("\n--- Table Start ---\n");
    for (int i = 0; i < TABLE_SIZE; i++){
        if (hash_table[i] == NULL)
            printf("\t %d \t --- \t\n", i);
        else {
            item *tmp = hash_table[i];
            printf("\t %d ", i);
            while(tmp != NULL){
                printf("\t --- \t %s", tmp->key);
                tmp = tmp->next;
            }
            printf("\n");
        }
    }
    printf("--- Table End ---");
}

int main(){

    // Initialise hash table
    init_hash_table();
    char letters[] = "ABCDEFGHIJ";

    // Insert data
    for (int i = 0; i < 10; i++){
        item itemN = {.key = letters[i]};
        printf("%s ", itemN.key);
        printf("%p\n", &itemN);
        insert_item(&itemN);
    }

    // Print the table
    print_table();

    return 0;
} 

本质上,我希望将 10 个条目添加到哈希表中,每个条目都是唯一的,键是不同的字母(A 到 J)。问题是 main 中的每个 itemN 在内存中具有相同的地址,因此每次都会覆盖相同的指针。因此我的输出看起来像:

A 0061FEB0
B 0061FEB0
C 0061FEB0
D 0061FEB0
E 0061FEB0
F 0061FEB0
G 0061FEB0
H 0061FEB0
I 0061FEB0
J 0061FEB0

--- Table Start ---
         0       ---
         1       ---
         2       ---
         3       ---     J
         4       ---
         5       ---
         6       ---     J
         7       ---     J
         8       ---     J
         9       ---     J
         10      ---     J
         11      ---     J
         12      ---     J
         13      ---     J
         14      ---     J
         15      ---
--- Table End ---

问题是,如何在循环中生成具有唯一地址的新项目变量?这似乎是非常标准的实现功能,因为我们不能总是手动初始化变量。对不起,如果我遗漏了一些明显的东西!

谢谢

标签: cpointershashmaphashtable

解决方案


代码不断插入相同的项目。 &itemN是本地对象的地址itemsN。该项目超出范围,循环后不再有效{ ...}

for (int i = 0; i < 10; i++){
  item itemN = {.key = letters[i]};
  ...
  insert_item(&itemN);
}
print_table();  // no longer valid for code to use `&itemN`.

.key = letters[i]也是无效的,因为它试图分配 charchar *. 这意味着警告没有完全启用。节省时间,启用它们。


也许插入 10 个不同item的 s。

item items[10] = { 0 };
for (int i = 0; i < 10; i++){
    items[i].key[0] = letters[i];
    printf("%s ", items[i].key);
    printf("%p\n", &item[i]);
    insert_item(&items[i]);
}

GTG


推荐阅读