您好,有人可以帮我找出导致问题的原因吗?出于某种原因, find_hash 函数给我带来了问题。它应该失败if(table -> buckets_array[i] != NULL){
,if(table -> buckets_array[i] != '\0'){
但事实并非如此,它会进行下一次检查,这给了我一个分段错误。自从我最初将它设置为 table -> buckets_array[i] = NULL 以来,是什么导致前 2 个 if 语句通过?
编辑:感谢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++;
}
}