0

我正在使用 C 语言尝试创建一个霍夫曼解码器。这段代码只有在 codearray 未初始化时才有效,否则它会给我一个分段错误。但是,valgrind 抱怨如果我这样做,codearray 是未初始化的。我用 ddd 完成了它,一旦调用 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);
4

2 回答 2

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);
}
于 2011-11-26T23:50:53.650 回答
0

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

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

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

strcpy(codearray[counter],code);

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

您必须为字符串的副本分配内存,例如使用strdup()而不是strcpy().

于 2011-11-26T23:18:36.557 回答