0

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

    #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;
   }
4

3 回答 3

3

这个:

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. 然后指针在循环中被取消引用,造成混乱。

于 2012-12-17T14:54:31.353 回答
1
    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->hashtableH->hashtable[0]0。0 也是如此,因此H->hashtable[toofer]->INSIDE取消引用空指针。

于 2012-12-17T14:56:58.633 回答
0
H->hashtable = (hashnode*) malloc(100003*sizeof(hashnode));

应该更好

...sizeof(struct Hashnode)...
于 2012-12-17T14:59:21.057 回答