2011-11-26 15 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