2016-08-22 71 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 
相關問題