Cで単純なハッシュテーブルを作成しようとしていますが、表示されているコードでテストすると、非常に奇妙なセグメンテーション違反が発生しますmain()
。
デザイン:サイズ10,000の基になる配列を持つハッシュテーブルがあります。struct node_t
(またはnode
)ポインターの配列の先頭へのダブルポインターを保持します。put()
ハッシュテーブルに何かを入れたいときnode
は、適切な場所にある要素がであるかどうかを確認しNULL
ます。そうである場合は、スポットを埋めるために新しいノードを作成します。そうでない場合は、衝突がある場合は、衝突しているノードからリンクリストを作成します。
シナリオ:では、ハッシュテーブルに3328という番号main()
を付けようとしています。put()
代わりに、プログラムはsegfaultsします。put()
前の例は正常に機能し、すべての初期ポインタをNULLに設定したことがはっきりとわかるので、これは私には意味がありません。私の知る限り、ハッシュテーブルの場所3328を参照するポインターは、put()
関数で逆参照するとsegfaultが発生するため、NULLに設定されません。私のメイン関数は、すべてのポインタをNULLに設定する必要があるようですが...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int TABLE_SIZE = 10000;
typedef struct node_t {
int key;
int value;
struct node_t* next;
} node;
node** table;
inline node** get_node_address(int key) {
key = (key > -key ? key : -key) % TABLE_SIZE;
return (node**) (table + key * sizeof(node*));
}
inline node* new_node(int key, int value) {
node* n = malloc(sizeof(node));
n->key = key;
n->value = value;
n->next = NULL;
return n;
}
void put(int key, int value) {
node** n = (node**) get_node_address(key);
node* iterator = (node*) *n;
if (*n == NULL) {
*n = new_node(key, value);
} else {
while (iterator->next != NULL)
iterator = iterator->next;
iterator->next = new_node(key, value);
}
}
int* get(int key) {
node* iterator = (node*) *get_node_address(key);
while (iterator != NULL && iterator->key != key) {
iterator = iterator->next;
}
if (iterator == NULL)
return NULL;
else
return &(iterator->value);
}
int main() {
printf("Starting..\n");
int i;
table = malloc(sizeof(node*) * TABLE_SIZE);
memset(table, 0, sizeof(node*) * TABLE_SIZE);
for (i = 0; i < TABLE_SIZE; i++) {
table[i] = NULL;
printf("setting %x\n", &table[i]);
}
printf("before bad: %x\n", *get_node_address(3327));
printf("bad address: %x\n", *get_node_address(3328));
printf("last address: %x\n", table + sizeof(node*) * TABLE_SIZE);
printf("Hashing...\n");
put(3328, 3338);
printf("%d", *get(3328));
return 0;
}