C代码似乎工作,但valgrind说数组没有初始化

时间:2014-10-16 05:19:34

标签: c token valgrind

我目前正在开展一个项目,我自己创建了自己的标记器。我的代码编译并正常工作,但valgrind给出了错误:

==2572== Conditional jump or move depends on uninitialised value(s)
==2572==    at 0x4C2B308: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==2572==    by 0x400FCB: strdup (Lex1.c:173)
==2572==    by 0x400EBA: lex (Lex1.c:140)
==2572==    by 0x400A3B: main (mainLex.c:34)
==2572== 
==2572== Conditional jump or move depends on uninitialised value(s)
==2572==    at 0x4C2B35B: strcpy (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==2572==    by 0x400FFC: strdup (Lex1.c:177)
==2572==    by 0x400EBA: lex (Lex1.c:140)

lex中的第140行是" temp->文本"以下代码中的行:

token *head, *temp, *right, *temp1;
char *line1 = strdup(line);
char *curr = separatebetter(line1);
temp = (token *)malloc(sizeof(token));
temp->text=strdup(curr);

奇怪的是我可以打印出curr的值,但是根据我的假设,valgrind会说curr在任何时候都没有初始化,尽管我很清楚地初始化它。

在strdup中valgrind引用的两行是:

int n = strlen(str) + 1;
strcpy(dup, str);

而独立的相关代码是:

char *separatebetter (char *arr)
{
    int status=0;
    static char* perm;
    if (arr!=NULL)
    {
        perm=arr;
    }
    if((perm[0]=='\0')||(perm[0]=='\n'))
    {
        return NULL;
    }
    if (strcspn(perm, "<|>&")==0)
    {
        status=1;
    }
    if (strcspn(perm, ";()")==0)
    {
        status=2;
    }
    char *toke = perm;
    char *temp;
    //Status is set to 1 or 2
    if (status==1)
    {
        printf("here\n");
        temp=toke;
        char *temp1=malloc(strlen(temp)*sizeof(char));
        temp1=temp;
        char *final = malloc(3*sizeof(char));
        temp1++;
        if(temp[0]==temp1[0])
        {
            final[0]=temp[0];
            final[1]=temp[0];
            *temp='\0';
            temp++;
            *temp='\0';
            perm=temp+1;
            return final;
        }
        else
        {
            final[0]=temp[0];
            final[1]='\0';
            *temp='\0';
            perm=temp+1;
            return final;
        }
    }
    else if (status==2)
    {
        temp=toke;
        char *final = malloc(2*sizeof(char));
        final[0]=temp[0];
        final[1]='\0';
        *temp='\0';
        perm=temp+1;
        return final;
    }
    perm[0]='\0';
    return toke;
}
编辑:我已经尝试过printf curr,虽然我得到了输出,但valgrind还告诉我

==6625== Conditional jump or move depends on uninitialised value(s)
==6625==    at 0x4E7AB5B: vfprintf (in /usr/lib64/libc-2.17.so)
==6625==    by 0x4E83CD8: printf (in /usr/lib64/libc-2.17.so)
==6625==    by 0x400EA8: lex (Lex1.c:138)
==6625==    by 0x400A3B: main (mainLex.c:34)

我认为curr的初始化是个问题我错了吗?

1 个答案:

答案 0 :(得分:2)

这段代码显然是错误的:

char *curr = malloc(100*sizeof(char));
curr = separatebetter(line1);

您分配内存,然后使用separatebetter()中的值覆盖指向它的唯一指针。这是一个直接泄漏。也许您打算使用strcpy()

strcpy(curr, separatebetter(line1));

我需要查看separatebetter()的作用 - 但这不是您正在运行的代码,因为它无法编译:

if (strcspn(perm, ";()")==0)
{
    status=2;
}
char *toke = perm;
char *temp;
//Status is set to 1 or 2
else if (status==1)

else无法在那里编译;前面的语句是变量声明。这让我们很难知道出了什么问题。给出声称正在运行的不可编译代码是非常烦人的。这使得很难知道什么是可信任的。

您的函数可以在此代码之前返回NULL - 并且strdup(NULL)的行为未定义,strcpy()在被告知从(或)复制时的行为也是如此一个NULL指针。您无法使用separatebetter()的返回值,直到您确定它不为空。

以下代码也重复了内存泄漏问题:

{
    printf("here\n");
    temp=toke;
    char *temp1=malloc(strlen(temp)*sizeof(char));
    temp1=temp;

同样,也许您打算使用strcpy()

    strcpy(temp1, temp);

separatebetter()的顶部,您有:

static char* perm;
if (arr!=NULL)
{
    perm=arr;
}
if((perm[0]=='\0')||(perm[0]=='\n'))
{
    return NULL;
}
if (strcspn(perm, "<|>&")==0)
{
    status=1;
}
if (strcspn(perm, ";()")==0)
{
    status=2;
}
char *toke = perm;

static char *perm令人费解。 arr赋予它有时令人费解。使用char *toke = perm;确实令人费解。先前的代码并不总是设置perm,因此有时它会从之前调用分配给它的函数中得到一个指针。该指针可能仍然有效,也可能不有效。我想你需要重新考虑整个separatebetter()

相信你的工具! (特别相信valgrind!)