2011-11-26 21 views
0

我正在C中嘗試創建一個huffman解碼器。這段代碼只在codearray進入未初始化時才起作用,否則會給我一個分段錯誤。然而,valgrind抱怨說,如果我這樣做的話,codearray是未初始化的。我用ddd進行了檢查,一旦strcpy被調用,segmentaion錯誤就會發生,我不知道爲什麼。如果目標字符串未初始化,strcpy的行爲會有所不同

void printtree_inorder(node* n,char* code,char* letarray,char** codearray) 
{ 
    if (n == NULL) { 
     return; 
    } 
    static int counter=0; 
    appenddigit(code,'0'); 
    printtree_inorder(n -> left,code,letarray,codearray); 
    remdigit(code); 
    if (n->let!='\0') { 
     letarray[counter]=n->let; 
     strcpy(codearray[counter],code); 
     counter++; 
    } 
    appenddigit(code,'1'); 
    printtree_inorder(n -> right,code,letarray,codearray); 
    remdigit(code); 
} 

下面是調用函數:

char code[100]={'\0'}; 
char** codearray=(char**)malloc(numchars*sizeof(char*)); 
for (i=0;i<numchars;i++) { 
    codearray[i]=(char*)malloc(100*sizeof(char)); 
} 


char* letarray=(char*)malloc((numchars+1)*sizeof(char)); 
letarray[0]='\0'; 

printtree_inorder(root,code,letarray,codearray); 
+0

你也可以說做的分配和調用此函數 –

+0

什麼appenddigit和remdigit做的代碼? – David

+0

numchars的值是什麼?也爲什麼你的櫃檯宣佈靜態? –

回答

0

大概在「初始化」調用數組是不是真的正確地全部初始化,因此該功能崩潰。

當「未初始化」時,數組可能包含(偶然)不會導致分段錯誤的值,具體取決於程序以前使用的內存的結果是否被用於codearray

函數試圖將一個字符串拷貝到哪裏codearray[counter]點:

strcpy(codearray[counter],code); 

在函數調用你展示這codearray[counter]是一個隨機值,因爲只有陣列malloc分配,但要素間沒有」 t初始化爲任何特定值。 strcpy()然後嘗試寫入該隨機存儲器地址。

您必須爲字符串的副本分配內存,例如通過使用strdup()而不是strcpy()

+0

我從來沒有聽說過strdup,但我會這樣使用它嗎? codearray [計數器] =的strdup(代碼,100)? –

+0

請參閱:http://pubs.opengroup.org/onlinepubs/009604499/functions/strdup.html – sth

+0

該數組的元素分配爲 –

1
for (i=0;i<numchars;i++) { 
    codearray[i]=(char*)malloc(100*sizeof(char)); 
} 

這是你說的代碼嗎?它並不是真正的初始化代碼,它正在爲數據代碼騰出空間。

char** codearray=(char**)malloc(numchars*sizeof(char*)); 

只是創建了一個char *數組,但它們並不指向任何有效的內存。因此,你的「初始化代碼」只是確保你的內存是正確創建的。

另一件事真正讓我害怕的是,你的計數器變量是靜態的。 主叫

printtree_inorder(root,code,letarray,codearray); 
printtree_inorder(root,code,letarray,codearray); 

也將結束段故障,因爲計數器將>然後NUMCHARS當調用它的第二時間(從外面)。 所以,讓我們重寫代碼了一下,使其更加安全

char* code = (char *)malloc(numchars + 1); 
memset(code, 0, numchars + 1); 

char* letarray = (char *)malloc(numchars + 1); 
memset(letarray, 0, numchars + 1); 

char** codearray = (char **)malloc(numchars * sizeof(char *)); 
memset(codearray, 0, numchars * sizeof(char *)); 

printtree_inorder(root, code, letarray, codearray, 0); 

free(code); 
// do not forget the free the other allocations later as well as 


void printtree_inorder(node* n,char* code,char* letarray,char** codearray, int counter) 
{ 
    if (n == NULL) { 
     return; 
    } 
    appenddigit(code,'0'); 
    printtree_inorder(n -> left,code,letarray,codearray, counter); 
    remdigit(code); 
    if (n->let!='\0') 
    { 
     letarray[counter] = n->let; 
     codearray[counter] = strdup(code); 
     ++counter; 
    } 
    appenddigit(code,'1'); 
    printtree_inorder(n -> right,code,letarray,codearray, counter); 
    remdigit(code); 
} 
+0

這似乎工作,但後來當我調用strcmp(「string」,codearray [ i])它崩潰與分段錯誤 –

+0

@Free_D,你是積極的,我是<那麼numchars ?,「字符串」被正確初始化(我猜,「字符串」不是真的「字符串」,但一些其他變量),並且你沒有釋放介於兩者之間的代碼陣列內存? – esskar