0

当 valgrind 运行这个程序(实现一种简单类型的数据压缩)时,它会报告“条件跳转取决于未初始化的值”。它也偶尔会出现段错误。问题是,我似乎无法确定哪个变量未初始化。我的 CS 教授提到“您的代码不能确保字符串正确以空值结尾”,但我看不出在哪里。

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 静态分析器* 确定了这一点,该分析器在前两个诊断中发现了这个问题(以及一个无关的、无害的错误作为第三个):

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])导致两个 Clang 诊断以及 Valgrind 错误消失。

*: 命令行:clang --analyze -Wall 14968829.c -o 14968829

于 2013-02-19T22:40:21.087 回答