C 中指针的哈希表



我正在尝试构建一个初始化哈希表,其指针指向程序中的另一个结构。 但是当我尝试初始化(H)时,它似乎给了我一个段错误。我想我可能分配了不正确的内存,但我不确定这是否是分段错误的实际含义。 它的设置方式,H->hashtable应该是一个哈希节点数组,对吧? 哈希节点本身是指向我的其他结构的指针。 为什么我只在初始化时出现 seg 错误?

    #include <stdio.h>
    #include <stdlib.h>
    typedef struct Position{
        char data[12];
        struct Hashnode *previous;
        struct Position *next;
        char letter;
        char direction[5];
    } *position;
    typedef struct Hashnode{
       struct Position *INSIDE;
    } *hashnode;
    typedef struct hash_table{
       hashnode *hashtable
    } *HTABLE;

    HTABLE NewHashtable(){
     HTABLE H = (HTABLE) malloc(sizeof(struct hash_table));
     if(H == NULL){ printf("Malloc for new hashtable failed."); exit(1);}
     return H;
    }

    void initialize(HTABLE H){
        H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));
        int toofer;
        for(toofer = 0; toofer<100003; toofer++){
                 H->hashtable[toofer]->INSIDE = NULL;
                 }
            }
   int main(){
       HTABLE H = NewHashtable();
       initialize(H);
       return 0;
   }

这个:

HTABLE H = (HTABLE) malloc(sizeof(struct hash_table));

太可怕了。它将typedef :ed指针(为什么人们仍然这样做?)与底层struct名称混合在一起,使读者的工作是确保它们匹配。另外,这个演员阵容也是一个坏主意。

它应该是:

HTABLE H = malloc(sizeof *H);

如果你坚持保持typedef.

也就是说,initialize()中的代码可能未能通过其malloc()调用,在被依赖之前不会对其进行检查。这是一个非常糟糕的主意。

此外,对于究竟分配了什么,也存在困惑。malloc()代码分配100003*sizeof(hashnode),但hashnode(再次)typedef:ed作为指针,而不是struct。然后指针在循环中被取消引用,从而导致混乱。

    H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));
    int toofer;
    for(toofer = 0; toofer<100003; toofer++){
             H->hashtable[toofer]->INSIDE = NULL;
             }
        }

第一行为H->hashtable分配了一堆内存。它包含随机垃圾。

因此,当你进入循环时,H->hashtable[0]是随机垃圾(因为H->hashtable都是随机垃圾)。但是您尝试在循环中跟踪该随机垃圾指针。取消引用未初始化的指针是获取分段错误的最快方法。

这里有一种方法可以帮助您查看它。假设您决定将内存归零以确保安全。您的代码将是:

    H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));
    memset(H->hashtable, 0, 100003 * sizeof(hashnode));
    int toofer;
    for(toofer = 0; toofer<100003; toofer++){
             H->hashtable[toofer]->INSIDE = NULL;
             }
        }

显然,在那memset之后,*(H->hashtable)是0,因为这会将H->hashtable全部设置为0。所以H->hashtable[0]也是 0,因此H->hashtable[toofer]->INSIDE取消引用空指针。

H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));

应该最好是

...sizeof(struct Hashnode)...

最新更新