2016-08-22 4 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; 
} 

を言葉、そしてプリントを読み込み、保存する:私が実行しているコードは次のようになります。例えば、入力が「1」「2」は「3」の出力は次のようになりました場合:左の列は周波数であり、右側がキーである場合は

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

「htable」とは何ですか? 'htablerec'構造体の不透明な型別名ですか? –

+0

@JoachimPileborgそれは恐ろしい型付きポインタと思われる... – joop

答えて

0

最初に表示されているものは、コンパイラに表示されるエラーではなく、警告のみです。

h->keys[initial_index]charmalloc/emallocに対しリターンボイドポインタです:ので、何をやっている

は、あなたが望んでいるものではありません。

1

char*は、charへのポインタ(ヌルで終了する文字列)があることを意味します。

char *keys; 

しかし、あなたのコードでは、あなたは、単一のcharへのポインタを代入している:h->keysのタイプはchar *あるので、

h->keys[initial_index] = emalloc(strlen(str)+1 * sizeof str[0]); 

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 
関連する問題