我有代码:
else if ((strtolnum=(strtol(&oldline[b+1],NULL,10)))>0)
{
char* excl = malloc(3*sizeof(char));
excl[0]=oldline[b];
excl[1]=oldline[b+1];
for (int j = 0; j<strtolnum; j++)
{
llist=llist->nextcmd;
}
struct token *p1;
struct token *save1 = llist->cmmd;
char *arra1 = malloc(sizeof(char));
memset(arra1, '\0', 1);
for (p1 = llist->cmmd; p1 != NULL; p1 = p1->next) {
arra = realloc(arra1, strlen(arra1)+strlen(p1->text)+2);
strcat(arra, p1->text);
if (p1->next!=NULL)
{
strcat(arra1, " ");
}// printing token and type
}
printf("%s excl\n", excl); //Line 137
oldline=strreplace(oldline,excl,arra1); //Line 138
llist->cmmd=save1;
for (int j = 0; j<(f-strtolnum); j++)
{
llist=llist->nextcmd;
}
*status=1;
size_t a = sizeof(excl);
memset(excl,'\0', a);
}
代码应该完成的是获取一行前面的第一个整数,其前面是感叹号部分,例如!3,并将其放在excl中(然后执行其他正常工作的东西)。
但是,当我不止一次运行循环时,我发现excl通常在结尾有一个随机字符,例如当我尝试printf它时它显示为“!3e”。 Valgrind显示以下错误:
==24878== Conditional jump or move depends on uninitialised value(s)
==24878== at 0x4E7AB5B: vfprintf (in /usr/lib64/libc-2.17.so)
==24878== by 0x4E83CD8: printf (in /usr/lib64/libc-2.17.so)
==24878== by 0x40130F: hExpand (Lex1.c:137)
==24878== by 0x400B6B: main (mainLex.c:27)
==24878==
==24878== Conditional jump or move depends on uninitialised value(s)
==24878== at 0x4C2B308: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==24878== by 0x4020D7: strreplace (Lex1.c:562)
==24878== by 0x40132C: hExpand (Lex1.c:138)
显然,在循环经过一次后,excl被单元化。有什么问题?
有关其他信息,cmmd是token类型的数据结构,llist是包含标记的全局静态数据结构。
答案 0 :(得分:2)
你没有终止excl
字符串; malloc()
返回随机垃圾。您可以考虑添加:
excl[2] = '\0';
你还用以下方式践踏了界限:
size_t a = sizeof(excl);
memset(excl,'\0', a);
您将4或8(32位或64位)分配给a
,然后写入多个字节,但您只为excl
分配了3个字节。