我正在尝试创建一个哈希表结构,其中包含键(字符串)数组以及每次键出现时的频率数组。我正在运行的代码如下所示:
#include <stdio.h>
#include <stdlib.h>
#include "mylib.h"
#include "htable.h"
int main(void){
htable h = htable_new(18143);
char word[256];
while(getword(word, sizeof word, stdin) !=EOF){
htable_insert(h, word);
}
htable_print(h);
htable_free(h);
return EXIT_SUCCESS;
}
创建一个新的哈希表,读入并存储单词,然后打印。例如,如果输入是“一个”“两个”“三个”,则输出看起来像:
1 one
1 two
1 three
左列是频率,右边是键。下面是实际的哈希表代码。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "mylib.h"
#include "htable.h"
struct htablerec{
int capacity;
int num_keys;
int *frequencies;
char *keys;
};
htable htable_new(int n){
int i;
htable result = emalloc(sizeof *result);
result->capacity = n;
result->num_keys = 0;
result->frequencies = emalloc(result->capacity * sizeof result->frequencies[0]);
result->keys = emalloc(result->capacity * sizeof result->keys[0]);
for(i=0;i<result->capacity;i++){
result->frequencies[i] = 0;
result->keys[i] = '\0';
}
return result;
}
static unsigned int htable_word_to_int(char *word){
unsigned int result = 0;
while(*word != '\0'){
result = (*word++ + 31 * result);
}
return result;
}
int htable_insert(htable h, char *str){
unsigned int key = htable_word_to_int(str);
unsigned int initial_index = (key % h->capacity);
if(h->keys[initial_index] == '\0'){
h->keys[initial_index] = emalloc(strlen(str)+1 * sizeof str[0]);
strcpy(h->keys[initial_index], str);
h->frequencies[initial_index] = 1;
h->num_keys++;
return 1;
}
else if(h->keys[initial_index] == *str){
h->frequencies[initial_index]++;
return h->frequencies[initial_index];
}
return 0;
}
void htable_print(htable h){
int i;
for(i=0;i<h->capacity;i++){
if(h->frequencies[i] >0){
printf("%d %s\n", h->frequencies[i], h->keys[i]);
}
}
}
void htable_free(htable h){
free(h->frequencies);
free(h->keys);
free(h);
}
基本上插入函数采用htable和字符串。它将字符串转换为整数并进行除法,以获得htable密钥数组大小的索引。如果索引为null,则没有任何内容,因此分配足够的内存并插入字符串,或者如果有相同的字符串增加频率。错误被抛弃:
assignment makes integer from pointer without a cast [-Wint-conversion]
h->keys[initial_index] = emalloc(strlen(str)+1 * sizeof str[0]);
^
htable.c:44:11: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy(h->keys[initial_index], str);
有问题的emalloc功能:
void *emalloc(size_t s){
void *result = malloc(s);
if(NULL == result){
fprintf(stderr, "Memory allocation error");
exit(EXIT_FAILURE);
}
return result;
}
由于%s参数的类型为int,因此也会导致打印错误。我仍然习惯了c中的指针,我确信这是基于错误的问题。
答案 0 :(得分:1)
char*
表示你有一个指向char的指针(可能是以空字符结尾的字符串)。
char *keys;
但是在你的代码中,你要指定一个指向一个char的指针:
h->keys[initial_index] = emalloc(strlen(str)+1 * sizeof str[0]);
由于h->keys
的类型为char *
,h->keys[initial_index]
为char
。您不能将void *
(或一般指针)分配给char
(或者至少期望任何有意义的结果)。
如果你想要很多字符串(即char *
的数组,A.K.A。一个字符串数组),你需要char **
。首先你需要malloc:
// in the struct
char **keys;
// when creating the struct
result->keys = emalloc(result->capacity * sizeof(char *));
for(i=0;i<result->capacity;i++){
result->frequencies[i] = 0;
result->keys[i] = emalloc(1); // say by default 1, you'll realloc later.
result->keys[i][0] = 0; // assign '\0' to it
答案 1 :(得分:0)
首先,你所展示的不是编译器看到的错误,而只是警告。
你所做的不是你想要的,因为:
:default => ''
是h->keys[initial_index]
,而char
返回空指针。