Search code examples
cvalgrind

Valgrind errors I want to fix


I have no compiler warnings and get correct output. Even so, valgrind complains a lot about my program.

#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 output

$ 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)

How can I make it free of errors?


Solution

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

    This loop never writes a \0 terminator to str, so subsequent calls to string functions (like strlen() and strcpy()) will run off the end of the string and trigger valgrind errors.

    Fixing this should take care of most, if not all, of your errors.