我要修复的 Valgrind 错误

Valgrind errors I want to fix

我没有编译器警告并且得到了正确的输出。即便如此,valgrind 对我的程序有很多抱怨。

#include <stdio.h>
#include <memory.h>
#include <stdlib.h>

int costs[95] = {0, 9, 6, 24, 29, 22, 24, 3, 12, 12, 17, 13, 7, 7, 4, 10, 22, 19, 22, 23, 21, 27, 26, 16, 23, 26, 8, 11,
                 10, 14, 10, 15, 32, 24, 29, 20, 26, 26, 20, 25, 25, 18, 18, 21, 16, 28, 25, 26, 23, 31, 28, 25, 16, 23,
                 19, 26, 18, 14, 22, 18, 10, 18, 7, 8, 3, 23, 25, 17, 25, 23, 18, 30, 21, 15, 20, 21, 16, 22, 18, 20,
                 25, 25, 13, 21, 17, 17, 13, 19, 13, 24, 19, 18, 12, 18, 9};

long solve(FILE *input) {
    int c;
    char str[100101];
    int i1 = 0;
    char *string = "";
    char *string1 = "";
    char *string2 = "";
    char *string3 = "";
    str[0] = 'c';
    while (EOF != (c = fgetc(input))) {
        str[i1++] = c;
    }
    int linecost = 0;
    for (int e = 0; e < strlen(str); e++) {
        if (str[e] == '\n') {;
            string1 = malloc(strlen(str) + 1);
            strcpy(string1, str);
            string3 = strtok_r(str, "\n", &string);
            while (string3 != NULL) {
                string2 = malloc(strlen(string3));
                strcpy(string2, string3);
                for (int i = 0; i < strlen(string2); i++) {
                    char strc3[1];
                    strcpy(strc3, &string2[i]);
                    int int1 = strc3[0];;
                    linecost = linecost + costs[int1 - 32];
                }
                printf("%d\n", linecost);
                linecost = 0;
                string3 = strtok_r(NULL, "\n", &string);
                free(string2);
            }
            free(string1);
        }
    }
    return 0;
}

int main(int argc, char **argv) {
    solve(stdin);
    return EXIT_SUCCESS;
}

Valgrind 输出

$ valgrind ./a.out < sample.in 
==8718== Memcheck, a memory error detector
==8718== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==8718== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==8718== Command: ./a.out
==8718== 
==8718== Conditional jump or move depends on uninitialised value(s)
==8718==    at 0x4C30F78: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x4009F5: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Conditional jump or move depends on uninitialised value(s)
==8718==    at 0x4C30F78: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x400862: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Conditional jump or move depends on uninitialised value(s)
==8718==    at 0x4C31068: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x40088E: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Invalid write of size 1
==8718==    at 0x4C3106F: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x4008EC: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718==  Address 0x5204195 is 0 bytes after a block of size 21 alloc'd
==8718==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x4008CC: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Invalid read of size 1
==8718==    at 0x4C30F74: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x400964: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718==  Address 0x5204195 is 0 bytes after a block of size 21 alloc'd
==8718==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x4008CC: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Invalid read of size 1
==8718==    at 0x4C31063: strcpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x40091D: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718==  Address 0x5204195 is 0 bytes after a block of size 21 alloc'd
==8718==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==8718==    by 0x4008CC: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
300
707
300
707
300
==8718== Use of uninitialised value of size 8
==8718==    at 0x4EC7C5D: strtok_r (strtok.S:172)
==8718==    by 0x4009A3: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Conditional jump or move depends on uninitialised value(s)
==8718==    at 0x4EC7C60: strtok_r (strtok.S:173)
==8718==    by 0x4009A3: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
707
==8718== Conditional jump or move depends on uninitialised value(s)
==8718==    at 0x4EC7BDC: strtok_r (strtok.S:94)
==8718==    by 0x4009A3: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Use of uninitialised value of size 8
==8718==    at 0x4EC7C1B: strtok_r (strtok.S:137)
==8718==    by 0x4009A3: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Use of uninitialised value of size 8
==8718==    at 0x4EC7C4B: strtok_r (strtok.S:163)
==8718==    by 0x4009A3: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== Conditional jump or move depends on uninitialised value(s)
==8718==    at 0x4EC7C76: strtok_r (strtok.S:184)
==8718==    by 0x4009A3: solve (in /home/developer/CLionProjects/carrots/a.out)
==8718==    by 0x400A3F: main (in /home/developer/CLionProjects/carrots/a.out)
==8718== 
==8718== 
==8718== HEAP SUMMARY:
==8718==     in use at exit: 0 bytes in 0 blocks
==8718==   total heap usage: 9 allocs, 9 frees, 5,480 bytes allocated
==8718== 
==8718== All heap blocks were freed -- no leaks are possible
==8718== 
==8718== For counts of detected and suppressed errors, rerun with: -v
==8718== Use --track-origins=yes to see where uninitialised values come from
==8718== ERROR SUMMARY: 396 errors from 12 contexts (suppressed: 0 from 0)

我怎样才能使它没有错误?

int i1 = 0;
…
str[0] = 'c';
while (EOF != (c = fgetc(input))) {
    str[i1++] = c;
}

此循环从不将 [=11=] 终止符写入 str,因此对字符串函数(如 strlen()strcpy())的后续调用将 运行 关闭字符串的末尾并触发 valgrind 错误。

解决这个问题应该可以解决大部分(如果不是全部)错误。