我正在尝试执行一个函数,从注释中清除给定代码。代码运行良好,但valgrind不喜欢它。输入包含应该清理的代码,我正在尝试将清理的代码保存为新代码。我尝试过不同的价值观与malloc,但valgrind似乎不喜欢它。我的代码如下:
char *remove_comments(char *input)
{
int a=0;
char *newcode=malloc((strlen(input))*sizeof(char));
int c=0;
while (a<strlen(input)){
if((*(input+a)=='/') && (*(input+a+1) =='/')){
while(*(input+a)!='\n'){
a++;
}
a++;
}
if(*(input+a)=='/' && *(input+a+1)=='*'){
int b=1;
while(b!=0){
a++;
if(*(input+a)=='*' && *(input+a+1)=='/'){
b--;
}
}
a++;
a++;
}
*(newcode+c)=*(input+a);
a++;
c++;
}
free(input);
return newcode;
}
valgrind的输出如下:
==30337== Conditional jump or move depends on uninitialised value(s)
==30337== at 0x402E50: mycompare_new (checkhelp.c:86)
==30337== by 0x401F23: test_remove_comments (test_source.c:81)
==30337== by 0x406FD2: srunner_run (in /tmp/user/ee67882dc0b6fb0b4d921c48de81577a5d87cccdc65e0a1580d6726d197a5e87/c-kurssi/Module_3/08_polisher/test/test)
==30337== by 0x402512: tmc_run_tests (tmc-check.c:134)
==30337== by 0x4021A7: main (test_source.c:206)
==30337== Uninitialised value was created by a heap allocation
==30337== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30337== by 0x402FF1: remove_comments (source.c.nomain.c:18)
==30337== by 0x401EBD: test_remove_comments (test_source.c:74)
==30337== by 0x406FD2: srunner_run (in /tmp/user/ee67882dc0b6fb0b4d921c48de81577a5d87cccdc65e0a1580d6726d197a5e87/c-kurssi/Module_3/08_polisher/test/test)
==30337== by 0x402512: tmc_run_tests (tmc-check.c:134)
==30337== by 0x4021A7: main (test_source.c:206)
==30337==
==30337== Conditional jump or move depends on uninitialised value(s)
==30337== at 0x402E50: mycompare_new (checkhelp.c:86)
==30337== by 0x4020BA: test_remove_comments (test_source.c:109)
==30337== by 0x406FD2: srunner_run (in /tmp/user/ee67882dc0b6fb0b4d921c48de81577a5d87cccdc65e0a1580d6726d197a5e87/c-kurssi/Module_3/08_polisher/test/test)
==30337== by 0x402512: tmc_run_tests (tmc-check.c:134)
==30337== by 0x4021A7: main (test_source.c:206)
==30337== Uninitialised value was created by a heap allocation
==30337== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30337== by 0x402FF1: remove_comments (source.c.nomain.c:18)
==30337== by 0x402045: test_remove_comments (test_source.c:102)
==30337== by 0x406FD2: srunner_run (in /tmp/user/ee67882dc0b6fb0b4d921c48de81577a5d87cccdc65e0a1580d6726d197a5e87/c-kurssi/Module_3/08_polisher/test/test)
==30337== by 0x402512: tmc_run_tests (tmc-check.c:134)
==30337== by 0x4021A7: main (test_source.c:206)
==30337==
最佳答案
这段代码有很多问题。
您使用的是C字符串,它是一个带有终端NUL(\0)的字符序列。但是,当您为新代码分配空间时,您只分配输入的长度,而不为NUL留出空间。您应该分配strlen(input)+1
。
循环每次通过循环时都将a
与strlen(input)
进行比较,这意味着您要重新计算看到的每个字符的输入长度。计算一次并将其保存在一个变量中,或者只是循环while (!input[a])
这将导致它在输入结束时碰到NUL时停止循环。*(input+a)
语法是不必要的;请使用input[a]
。
如果字符串的最后两个字节是“/”,或者如果代码中包含“/”,而不是“\n”,则内部while循环将在内存中循环,直到遇到“\n”。在字符串上循环时始终检查NUL,如果遇到NUL,则终止循环。与“/*…”的内环相同。。。*/“案例。
代码将错误地将“/*/”识别为注释。
如果输入在一行中包含两个注释,例如“/*X*/*Y*/”,则代码将无法识别第二个注释。它将跳过第一条注释,但随后将第二条注释的首字母“/”添加到newcode并继续。
在返回新代码之前,不能在其末尾添加NUL。
我想您在测试中得到了valgrind错误,因为您正在使用返回的字符串执行strcmp,而且由于它没有NUL终止,strcmp正在进入未初始化的堆内存。
关于c - valgrind问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42352745/