您好,有人可以帮我找到导致问题的原因吗?由于某种原因,find_hash函数给我带来了问题。它应该是if(table -> buckets_array[i] != NULL){
和if(table -> buckets_array[i] != '\0'){
失败,但它不是,它会进行下一次检查,这会给我一个分段错误。自从我最初将其设置为表格后,可能导致前2个if语句通过的原因 - > buckets_array [i] = NULL?
编辑:感谢wildplasser
我为find_hash函数提出了一个更好的解决方案。
if(table->buckets_array[table->hash_func(key)] == NULL){
return NULL;
}else{
return table -> buckets_array[table->hash_func(key)] -> data;
}
谢谢大家的帮助。
/*hash.h*/
#include<stdio.h>
#include<stdlib.h>
typedef struct data_{
char *key;
void *data;
struct data_ *next;
}data_el;
typedef struct hash_table_ {
void **order;
int *number_next_calls;
int *number_buckets;
int *buckets_size;
int *worst;
int *total;
float *average;
int (*hash_func)(char *);
int (*comp_func)(void*, void*);
data_el **buckets_array;
} hash_table, *Phash_table;
Phash_table new_hash(int size, int (*hash_func)(char *), int (*cmp_func)(void *, void *));
void free_hash(Phash_table table);
void insert_hash(Phash_table table, char *key, void *data);
void *find_hash(Phash_table table, char *key);
void stat_hash(Phash_table table, int *total, int *largest, float *average);
void *start_hash_walk(Phash_table table);
void *next_hash_walk(Phash_table table);
static void lower_case_word(char *w);
/*hash.c*/
#include"hash.h"
Phash_table new_hash(int size, int (*hash_func)(char *), int (*cmp_func)(void *, void *)){
int i;
Phash_table table_p;
hash_table hash_table;
table_p = (Phash_table)malloc(sizeof(hash_table));
/*Setting function pointers*/
table_p->hash_func = hash_func;
table_p->comp_func = cmp_func;
/*Create buckets array*/
table_p->buckets_array = (data_el **)malloc(sizeof(data_el *)*(size+1));
table_p->buckets_size = (int *)malloc(sizeof(int)*(size+1));
/*Setting order array*/
table_p->order = NULL;
/*Setting inital condictions*/
table_p->worst = (int *)malloc(sizeof(int));
table_p->total = (int *)malloc(sizeof(int));
table_p->average = (float *)malloc(sizeof(float));
table_p->number_buckets = (int *)malloc(sizeof(int));
*(table_p->number_buckets) = size;
for(i = 0; i < size; i++){
table_p->buckets_array[i] = NULL;
}
return table_p;
}
void free_hash(Phash_table table){
int i;
i = 0;
data_el *cur;
data_el *prev;
/*Free order array*/
if(table->order != NULL){
free(table->order);
}
/*Free Buckets array and buckets_size array*/
if(table ->buckets_array != NULL){
for(i=0; i < *(table->number_buckets); i++){
if(table->buckets_array[i] != NULL){
/*Travers the linked list and free it*/
cur = table->buckets_array[i];
prev = cur;
while((cur = cur->next) != NULL){
free(prev);
prev = cur;
}
/*Free the last node*/
free(cur);
}
}
}
free(table);
}
void insert_hash(Phash_table table, char *key, void *data){
int index;
data_el *p, *cur;
index = table->hash_func(key);
/*Head insertion*/
if(table->buckets_array[index] == NULL){
table->buckets_array[index] = (data_el *)malloc(sizeof(data_el));
table->buckets_array[index]->data = data;
table->buckets_array[index]->next = NULL;
table->buckets_array[index]->key = key;
}else{
cur = table->buckets_array[index];
p = (data_el *)malloc(sizeof(data_el));
p->key = key;
p->data = data;
p->next = cur;
cur = p;
table->buckets_array[index] = cur;
}
/*Update Total*/
*table->total += 1;
/*Update Bucket Size*/
(table->buckets_size[index]) +=1;
/*Updates Worst Case*/
if((table->buckets_size[index]) > *(table->worst)){
*(table->worst) = (table->buckets_size[index]);
}else{
*(table->worst) +=1;
}
/*Update Average*/
int temp_total,temp_buckets;
temp_total = *(table->total);
temp_buckets = *(table->number_buckets);
*(table->average)= (float)temp_total/(float)temp_buckets;
}
void *find_hash(Phash_table table, char *key){
int i;
i = 0;
while(1){
if(table->buckets_array[i] == '\0'){
printf("End of Array");
break;
}
if(table->buckets_array[i] != NULL){
printf("%Checking");
if(table->buckets_array[i] != '\0'){
if(table->buckets_array[i]->key != NULL){
if( strcmp(table->buckets_array[i]->key,key) == 0 ){
printf("Found it\n");
break;
}
}
}
}
i++;
}
if(table->buckets_array[i] != NULL){
printf("new asdasd %d", *((int *)table->buckets_array[i]->data));
return table->buckets_array[i]->data;
}else{
return NULL;
}
}
void stat_hash(Phash_table table, int *total, int *largest, float *average){
total = (table->total);
largest = (table->worst);
average = (table->average);
}
void *start_hash_walk(Phash_table table){
int i, max_buckets,step,next_calls;
step = 0;
data_el *cur;
next_calls = 0;
max_buckets = *(table ->number_buckets);
table->order = (void**)malloc(sizeof(void *)*(*(table->total)));
/*Set number_next_calls to 0*/
table->number_next_calls = &next_calls;
*(table->number_next_calls) = 0;
/*Traverse the ADT and put all data into order array*/
for(i = 0; i < max_buckets; i++){
if(table->buckets_array[i] != NULL){
cur = table->buckets_array[i];
while(cur){
table->order[step] = cur->data;
step ++;
cur = cur->next;
}
}
}
/*Bubble Short*/
int j,k;
for(j = 0; j < (step - 1);j++){
for(k = 0;k < (step -(j+1));k ++){
if((table->comp_func)(table->order[j],table->order[j+1]) < 5){
void *temp;
temp = table->order[j];
table->order[j] = table->order[j+1];
table->order[j+1] = temp;
printf("Swaping %s with %s\n",table->order[j],table->order[j+1]);
}
}
}
return table->order;
}
void *next_hash_walk(Phash_table table){
/*
Check the amount of times next_has_walk has been
if higher than total, it will return null
*/
if(*(table->number_next_calls) >= *(table->total)){
return NULL;
}else{
*(table->number_next_calls) = *(table->number_next_calls) + 1;
return table->order[*(table->number_next_calls)];
}
}
/*project4.c*/
#include"hash.h"
#define WORD_SIZE 40
#define DICTIONARY_SIZE 1000
#define TRUE 1
#define FALSE 0
int hash_function(char *word){
int sum,i;
i = 0;
sum = 0;
while(word[i] != '\0'){
sum = sum + word[i];
i++;
}
return sum%1000;
}
int main(void){
/*Creating buckets array*/
Phash_table dictionary;
void *test;
dictionary = new_hash(DICTIONARY_SIZE,hash_function,comp);
int i;
i = 0;
void *frequency[DICTIONARY_SIZE];
int char_index = 0, dictionary_size = 0, num_words = 0;
char c, word[WORD_SIZE];
printf("Parsing input ...\n");
while ((c = getchar()) != EOF) {
if ((c == ' ') || (c == ',') || (c == '.') || (c == '!') || (c == '"') ||
(c == ':') || (c == '\n')) {
/* End of a word */
if (char_index) {
/* Word is not empty */
word[char_index] = '\0';
lower_case_word(word);
if(!find_hash(dictionary,word) ){
insert_hash(dictionary,word,frequency[hash_function(word)]);
}
frequency[hash_function(word)]++;
char_index = 0;
num_words++;
}
}else{
word[char_index++] = c;
}
}
printf("There were %d words; %d unique words.\n", num_words,dictionary_size);
}
void lower_case_word(char *w){
int i = 0;
while (w[i] != '\0') {
w[i] = tolower(w[i]);
i++;
}
}
答案 0 :(得分:1)
这太复杂了。我会在代码中发表评论。
void *find_hash(Phash_table table, char *key){
int i;
i = 0;
while(1){
for()循环的绝佳位置。
if(table->buckets_array[i] == '\0'){
- &gt; buckets_array []是指向data_el指针数组的指针 '\ 0'是一个int(一个字符常量是C中的int)
printf("End of Array");
break;
}
if(table->buckets_array[i] != NULL){
你已经测试过了,并且已经退出了循环。条件总是如此。
printf("%Checking");
if(table->buckets_array[i] != '\0'){
无需第三次测试。
if(table->buckets_array[i]->key != NULL){
啊!现在我们到了节点的有效载荷
if( strcmp(table->buckets_array[i]->key,key) == 0 ){
printf("Found it\n");
break;
}
}
}
}
这里有大括号,我懒得读书,或算数(4)或加工它们。
i++;
}
if(table->buckets_array[i] != NULL){
你似乎真的喜欢这种情况。
printf("new asdasd %d", *((int *)table->buckets_array[i]->data));
return table->buckets_array[i]->data;
啊!有效载荷得到传递。您可以将打印保留给来电者。
}else{
return NULL;
}
}
缩小版本:
void *find_hash(Phash_table table, char *key){
int i;
unsigned i;
for (i=0; i < *table_p->number_buckets; i++){
data_el *cur;
for (cur = table->buckets_array[i]; cur != NULL; cur = cur->next ) {
if( strcmp(cur->key,key) ) continue;
return cur->data; /* found it ! */
}
}
return NULL;
}
另外:malloc int-size对象(如 table_p-&gt; number_buckets)更实际的是将定义更改为:
typedef struct hash_table_ {
void **order; /* This might be intended as a permutation array ? */
unsigned number_next_calls;
unsigned int number_buckets;
unsigned int *buckets_size; /* I think this was intended as a histogram */
unsigned int worst;
unsigned int total;
float average;
int (*hash_func)(char *);
int (*comp_func)(void*, void*);
data_el **buckets_array;
} hash_table, *Phash_table;
隐藏在typedef后面的指针(比如你的Phash_table)在一般被认为是不好的做法。
正如我昨天评论的那样,你的哈希函数很危险,因为它返回一个signed int。它可能会产生负面指数。 (这也是非常糟糕的,碰撞方面,因为“ABC”,“ACB”,“CAB”都散列到相同的值。更好地使用K&amp; R,FNV或Jenkins。)
答案 1 :(得分:0)
也许您可以更正代码,以便它是您正在测试的内容。也许包括所有必要的位,以便我们可以编译它(我喜欢)。
请注意,find_hash
没有返回值,但在调用insert_hash
之前调用它会给您带来麻烦。
编辑(现已显示完整代码)
函数comp
在new_hash
的调用中 - 因此无法编译。
你在做什么与mallocs:
table_p->worst = (int *)malloc(sizeof(int));
table_p->total = (int *)malloc(sizeof(int));
table_p->average = (float *)malloc(sizeof(float));
table_p->number_buckets = (int *)malloc(sizeof(int));
无论如何都不应该从malloc返回,但是在这里你要为int分配空间然后告诉编译器你为int *
分配了空间。这些字段实际上需要成为指针吗?
在你的find_hash中,循环应该是for:
for (i=0; table->buckets_array[i] == ...; ++i) {
etc
}
但是,正如sarnold所说,为什么对table->buckets_array[i]
(0)和NULL
(0)进行'\0'
测试。这是非常奇怪的事情。
我不会花太多时间调试它。相反,我建议对代码进行审查(或让同事审查它)并整理出一些问题。其中包括:
const
添加到未更改的参数