如何在C中初始化哈希表

时间:2017-11-15 04:53:13

标签: c data-structures segmentation-fault

我在C中有一个创建哈希表的程序。 memset很好,但我想用for循环初始化。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define HSZ 127
#define HASHING(x) ((x)%HSZ)

struct node_t{
    int val;
    struct node_t *next;
};

struct node_t *hash_table[HSZ];

void init(void){
    int i;
    //memset(hash_table,0,sizeof(hash_table));
    for(i=0; i<HSZ; i++){
        hash_table[i]->val = 0;
        hash_table[i]->next = NULL;
    }
}

void insert_hash(int value){
    int key = HASHING(value);
    struct node_t *newNode = (struct node_t*)malloc(sizeof(struct node_t));

    newNode->val = value;
    newNode->next = NULL;

    if(hash_table[key] == NULL){
        hash_table[key] = newNode;
    } else {
        newNode->next = hash_table[key];
        hash_table[key] = newNode;
    }
}

int delete_hash(int value){
    int key = HASHING(value);
    if (hash_table[key] == NULL)
        return 0;

    struct node_t *delNode = NULL;

    if (hash_table[key]->val == value){
        delNode = hash_table[key];
        hash_table[key] = hash_table[key]->next;
    } else {
        struct node_t *node = &hash_table[key];
        struct node_t *next = hash_table[key]->next;
        while (next){
            if (next->val == value){
                node->next = next->next;
                delNode = next;
                break;
            }
            node = next;
            next = node->next;
        }
    }
    return 1;
    free(delNode);
}
void PrintAllHashData()
{
    printf("###Print All Hash Data###\n");
    for (int i = 0; i < HSZ; i++){
        if (hash_table[i] != NULL){
            printf("idx : %d ", i);
            struct node_t *node = hash_table[i];
            while (node->next){
                printf("%d ", node->val);
                node = node->next;
            }
            printf("%d\n", node->val);
        }
    }
}

int main(void){
    init();
    insert_hash(1);
    insert_hash(3);
    insert_hash(128);
    PrintAllHashData();
}

看看这段代码。

for(i=0; i<HSZ; i++){
    hash_table[i]->val = 0;
    hash_table[i]->next = NULL;
}

我正在使用的IDE在编译代码时不会抛出编译错误,但在执行期间代码出现故障并被终止/拖延。我尝试调试代码,它在此行出错并停止,我认为BAD ACCESS指向分段错误。

然后,我将此行更改为

for(i=0; i<HSZ; i++){
    hash_table[i].val = 0;
    hash_table[i]->next = NULL;
}

但是,我收到了说明'structure type require instead of 'struct node_t *'

的编译错误

我认为我不清楚C中的struct。 如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

您正在处理的是未定义的行为。

参见struct node_t *hash_table[HSZ]; 因此,hash_table是数据类型HSZ的{​​{1}}(127)个指针数组。

当你这样做时,

struct node_t

for(i=0; i<HSZ; i++){ hash_table[i]->val = 0; hash_table[i]->next = NULL; } hash_table[0]指针并没有指向任何东西。 因此,应首先初始化它们(或所有它们)以指向类型为hash_table[126]的对象,然后您可以初始化它们。就此而言,使用struct node_t不会导致问题,因为memset正在用全零填充指针的内容。用全零填充指针和用指针指向的内存填充全零之间有区别。

试试这个,

memset

是完全错误的。

要解决您遇到的问题,您需要使用for(i=0; i<HSZ; i++){ hash_table[i].val = 0; hash_table[i]->next = NULL; } 动态分配内存。您可以在malloc循环中执行此操作。

for

答案 1 :(得分:1)

struct node_t *hash_table[HSZ]; 给你一组未设置的指针(即没有指向任何东西)

void init(void) {
    int i;
    // memset(hash_table,0,sizeof(hash_table));
    for (i = 0; i < HSZ; i++) {
        hash_table[i]->val = 0;
        hash_table[i]->next = NULL;

尝试写入无效指针,这会产生未定义的行为。

使数组成为结构数组(而不是指针):

struct node_t hash_table[HSZ];
...
/* note use of . instead of -> since we have structs not pointers */
hash_table[i].val = 0;

或分配必要的结构,以便数组指向某个东西:

for (i = 0; i < HSZ; i++) {
    hash_table[i] = malloc(sizeof(struct node_t));
    hash_table[i]->val = 0;
    hash_table[i]->next = NULL;
}

答案 2 :(得分:1)

struct node_t{
    int val;
    struct node_t *next;
};

struct node_t *hash_table[HSZ];

当你有*hash_table[HSZ]时,这个变量hash_table是一个指针。所以不管你的动作是什么,使用hash_table->,指针的语法,指向某个地方。 建议当你使用指针时,你应该总是分配内存hash_table[i] = malloc(sizeof(struct node_t));

struct node_t hash_table;

但是如果你像这样初始化你的变量,你可以使用hash_table.val = 0

所以赋值的方式取决于你如何声明你的varibles