c - valgrind 的问题

标签 c

我正在尝试执行一个从注释中清除给定代码的功能。该代码工作正常,但 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== 

最佳答案

这段代码有很多问题。

  1. 您正在使用 C 字符串,它们是带有终端 NUL (\0) 的字符序列。但是你给newcode分配空间的时候,你只分配了input的长度,没有给NUL留空间。您应该分配 strlen(input)+1

  2. 每次循环时,循环都会将 astrlen(input) 进行比较,这意味着您要为看到的每个字符重新计算输入的长度。计算一次并将其保存在变量中,或者只是循环 while (!input[a]) 这将导致它在输入末尾遇到 NUL 时停止循环。

  3. *(input+a) 语法是不必要的;使用输入[a]

  4. 如果字符串的最后两个字节是“//”,或者如果代码包含一个“//”但后面没有跟“\n”,那么内部 while 循环将遍历内存直到它遇到'\n'。在遍历字符串时始终检查 NUL 并在遇到 NUL 时终止循环。 “/* ... */”情况的内部循环也是如此。

  5. 代码会错误地将“/*/”识别为注释。

  6. 如果输入连续包含两个注释,例如“/*X*//*Y*/”,那么代码将无法识别第二个注释。它将跳过第一条评论,但随后将第二条评论的初始“/”添加到新代码并继续。

  7. 在返回 newcode 之前,您没有在其末尾添加 NUL。

我想您在测试中遇到了 valgrind 错误,因为您正在对返回的字符串执行 strcmp,并且由于它不是 NUL 终止的,strcmp 正在进入未初始化的堆内存。

关于c - valgrind 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42352745/

相关文章:

c - Glib 线程与 GMain 循环事件

c - 用 C 编写 shell,在某处关闭 stdin

c - 使用 libcurl 从 FTP 读取文件

c - 在 C89 中,如何将 double 浮点截断并拆分为两个 32 位字?

c++ - 如何获取拖入 Win32 应用程序的文件路径并将其删除?

c - 使用 getchar() 读取所有输入

c - 指向结构体的指针

c - 打乱用户输入的字符串

c - 逻辑错误?程序没有像我希望的那样工作

c - 从c中的文本文件中读取字符并存储在二维数组中问题