我在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
。
如何解决这个问题?
答案 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