2016-08-22 73 views
0

我试图创建一个散列表结构,其中包含键(字符串)数组以及每次键出现时的频率数组。我正在运行的代码如下所示:C - 分配内存并将字符串复制到散列表的数组中

#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; 
} 

它创建一个新的散列表,读入并存储单词,然后打印。 E.g如果输入是“一”“二”“三”的输出看起来像:

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的键数组的大小内的索引。如果索引为空,那么就没有任何东西可以分配足够的内存并插入字符串,或者如果有相同的字符串增加频率。错误被扔了过来:

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

什么是'htable'?它是'htablerec'结构的不透明类型别名吗? –

+0

@JoachimPileborg它甚至似乎是可怕的typedeffed指针... – joop

回答

0

首先,无论您显示的是编译器看到的错误,而只是警告。

你在做什么是不是你想要什么,因为:

h->keys[initial_index]charmalloc/emalloc返回一个空指针。

1

char*表示您有一个指向char的指针(可能是一个以null结尾的字符串)。

char *keys; 

但在你的代码,你要指定一个指向单个字符:

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 
相关问题