2012-10-24 67 views
0

好,我放在一起問題代碼的簡化示例:分段故障,在C初始化遞歸結構

#include "stdio.h" 
#include "string.h" 

struct Trie{ 
    //Holds sub-tries for letters a-z 
    struct Trie *sub[26]; 
    //Is this a substring, or a complete word? 
    int is_word; 
}; 
typedef struct Trie Trie; 

Trie dictionary; 

int main(int argc, char *argv[]){ 
    //A list of words 
    char *words[7] = {"the","of","and","to","a","in","that"}; 

    //Add the words to the Trie structure 
    int i=0, wordlen; 
    Trie *sub_dict; 
    for (;i<7; i++){ 
     //Reset 
     printf("NEW WORD\n"); 
     sub_dict = &dictionary; 
     //Add a word to the dictionary 
     int j=0, c; 
     while (c = words[i][j], c != '\0'){ 
      printf("char = %c\n",c); 
      //Initialize the sub-Trie 
      if (sub_dict->sub[c-97] == NULL) 
       sub_dict->sub[c-97] = (Trie*) malloc(sizeof(Trie*)); 
      //Set as new sub-trie 
      sub_dict = sub_dict->sub[c-97]; 
      j++; 
     } 
     sub_dict->is_word = 1; 
    } 
} 

基本上,我有保持「a」到「Z」的字母特里數據結構。我有一個應該在while循環中添加的單詞列表。不幸的是,我在循環中的不同位置出現了分段錯誤(取決於我何時運行它)。

我猜問題有事情做與線
sub_dict->sub[c-97] = (Trie*) malloc(sizeof(Trie*));
但我是新來C,所以我完全不知道發生了什麼事情。

回答

2

sub_dict->sub[c-97] = (Trie*) malloc(sizeof(Trie*)); 存在錯誤。

sizeof(Trie*)將在32位操作系統4,因爲Trie*是一個指針,而在32位操作系統指針的大小是4 ,你可以這樣做:sub_dict->sub[c-97] = (Trie*) malloc(sizeof(Trie));

+0

它爲什麼出現段錯誤,如果我做'特里溫度; sub_dict-> sub [c-97] = &temp;'而不是?不應該用'malloc'做同樣的事情嗎? – Azmisov

+1

因爲你去寫超出已分配內存的結束,所以你踐踏了'的malloc()'的控制信息,所以它得到了混淆有關的記憶它應該給你下一個。 –

1

你似乎假定,當你做

something = (Trie*) malloc(sizeof(Trie*)); 

然後該結構的內容被初始化爲零(例如,每個成員將以NULL開始)。 malloc()並非如此。你必須要麼使用calloc,或使用memset()分配後,將其重置。

事實上,我會打電話甚至在你的出發字典memset的是在安全方面。 (儘管全局和靜態變量are apparently initialized to zero,所以這可能不是你的情況下是必要的。)

+0

因此,將結構只是充滿了一堆垃圾呢? 'sub_dict-> sub [c-97] == NULL'是否只是運氣而已? – Azmisov

+1

是的;使用'calloc()'獲得歸零內存。 'malloc()'返回的數據可能包含任何垃圾;它最多被意外調零。 –