我正在尝试构建一个初始化哈希表,其指针指向程序中的另一个结构。 但是当我尝试初始化(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)...