0

valgrindがこのプログラムを実行すると(単純なタイプのデータ圧縮を実装する)、「条件付きジャンプは初期化されていない値に依存します」と報告します。また、時折セグフォールトします。問題は、どの変数が初期化されていないかを特定できないようです。私のCS教授は、「あなたのコードは文字列が正しくnullで終了していることを確認していません」と述べましたが、どこにあるのかわかりません。

https://gist.github.com/anonymous/9f6c87fb33985606a297

(編集-ここに実際のコードを追加しました:)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORDLIM 128
#define REPEAT for(;;)
struct word {
    char *cont;
    char *wsp;  
    int ctr;
}; 

char peekchar(void)
{
    char c;
    c = getchar();
    if(c != EOF) 
        ungetc(c, stdin);

    /* puts it back */    
    return c;
} 

struct word *getword()
{
    char cont[WORDLIM];
    char wsp[WORDLIM];
    cont[0] = '\0';
    wsp[0] = '\0';
    if (peekchar() == EOF) 
    {
        return NULL;
    }

    REPEAT{
        char c = getchar();
        char buf[2];
        buf[0]=c;
        buf[1]='\0';
        if (c == '\n' || c == ' ' || c == EOF)
        {
            if (c != EOF)
                strcat(wsp, buf);
            if (peekchar() != '\n' && peekchar() != ' ')
            {
                struct word *toret;
                toret = malloc(sizeof(struct word));
                toret->cont = malloc(strlen(cont) + 1);
                strcpy(toret->cont, cont);
                toret->wsp = malloc(strlen(wsp) + 1);
                strcpy(toret->wsp, wsp);
                toret->ctr = -1;
                return toret;
            }
            continue;
        }
        else {
            strcat(cont, buf);
            continue;
        }
    }
    printf("PANIC PANIC PANIC THIS IS GOING WROOOOONG!!!!!\n");
}

void numbrify(struct word **wordlist)
{
    int oc = 0;
    int roc = oc;
    struct word *w;
    while ((w = wordlist[oc]) != NULL){
        int ic;
        if (w->ctr == -1){
            for (ic = oc + 1; wordlist[ic] != NULL; ic++){
                if (!strcmp(wordlist[ic]->cont, w->cont)){
                    //printf("**found match between %s and %s**\n", wordlist[ic]->cont, w->cont);
                    wordlist[ic]->ctr = roc;
                }
            }
            if (w->cont[0]!='\0')
        roc++;
        }
        oc++;
    }
} 

int main(void){
    struct word *wlist[4096];
    int i = 0;
    struct word *w;
    for (i = 0; (w = getword()) != NULL; i++){
        wlist[i]=w;
    }

    wlist[i+1] = NULL;
    numbrify(wlist);
    i = 0;
    for (i = 0; wlist[i]!=NULL; i++){
        if (wlist[i]->ctr == -1) 
            printf("%s%s", wlist[i]->cont, wlist[i]->wsp);
        else 
            printf("%d%s", wlist[i]->ctr, wlist[i]->wsp);
            //printf("'%s'\t'%s'\t%d\n", wlist[i]->cont, wlist[i]->wsp, wlist[i]->ctr);
    }

    return 0;
}
4

1 に答える 1

1

プログラムの85行目:

wlist[i+1] = NULL;

iすでに配列内の未使用のエントリを指しているため、に割り当てるNULLwlist[i+1]、終了前に未定義の値が残ります。

私はこれをClang静的アナライザー*を実行することで判断しました。これにより、最初の2つの診断でこの問題が特定されました(3番目の診断では無関係で無害なエラーも同様です)。

14968829.c:62:12: warning: Assigned value is garbage or undefined
        while ((w = wordlist[oc]) != NULL){
                  ^ ~~~~~~~~~~~~
14968829.c:65:35: warning: The left operand of '!=' is a garbage value
                        for (ic = oc + 1; wordlist[ic] != NULL; ic++){
                                          ~~~~~~~~~~~~ ^
14968829.c:87:2: warning: Value stored to 'i' is never read
        i = 0;
        ^   ~

この問題を(に変更wlist[i+1]してwlist[i])修正すると、2つのClang診断が消え、Valgrindエラーが発生しました。

*: コマンドライン:clang --analyze -Wall 14968829.c -o 14968829

于 2013-02-19T22:40:21.087 に答える