如果目标字符串未初始化,则strcpy的行为会有所不同

时间:2011-11-26 23:10:35

标签: c string huffman-code

我正在C中尝试创建一个霍夫曼解码器。这段代码只有在codearray未初始化时才有效,否则会给我一个分段错误。然而,valgrind抱怨如果我这样做的话,代码阵列是未初始化的。我用ddd完成了它,一旦strcpy被调用就发生了segmentaion故障,我无法弄明白为什么。

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);

2 个答案:

答案 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);

也将以分段错误结束,因为计数器将>然后第二次(从外面)调用它时的数字。 所以,让我们重写你的代码并使其更安全

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);
}

答案 1 :(得分:0)

可能在“初始化”调用中,数组根本没有被正确初始化,因此函数崩溃。

当“未初始化”时,数组可能包含(偶然)不会导致分段错误的值,具体取决于程序先前使用最终用于codearray的内存所执行的操作

该函数尝试将字符串复制到codearray[counter]指向的位置:

strcpy(codearray[counter],code);

在函数调用中,您显示此codearray[counter]是一个随机值,因为只有数组是malloc'ed,但元素未初始化为任何特定值。 strcpy()然后尝试写入该随机存储器地址。

您必须为字符串副本分配内存,例如使用strdup()代替strcpy()