我目前正在开展一个项目,我自己创建了自己的标记器。我的代码编译并正常工作,但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的初始化是个问题我错了吗?
答案 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
!)