Search code examples
cvalgrind

valgrind - Address is 2 bytes before a block of size 16 alloc'd


I'm having a bit of an issue trying to understand why valgrind is telling me I am going out of bounds in a char *array.

Whenever I try to iterate the array backwards starting from before the nul byte. It throws me the error that I am accessing memory I am not supposed to.

This is my first function:

char *ReadLineFile(FILE *infile) {
    int initSize = 16;
    char *string = NULL;
    string = malloc(sizeof(char) * initSize);
    if(string == NULL){
        exit(-1);
    }

    char val;
    int valSize = 0;
    while((val = fgetc(infile)) != EOF){
        if(val == '\n'){
            break;
        }

        if(valSize == initSize){
            initSize *= 2;
            string = realloc(string, initSize * sizeof(char));
        }

        string[valSize++] = val;
    }

    if(valSize == initSize){
        initSize++;
        string = realloc(string, initSize * sizeof(char));
    }

    string[valSize++] = '\0';

    return trimString(string);
}

This is my second function:

char *trimString(char *string) {
    int start = 0;
    int end = strlen(string);

    while(string[start] == ' '){start++;}
    while(string[end-2] == ' '){end--;}  // the [end-2] causes the error in valgrind

    int trimLen = end - start;
    char *trimmedStr = malloc(sizeof(char) * (trimLen + 1));
    if(trimmedStr == NULL){
        exit(-1);
    }

    int i = 0;
    while(start != end){
        trimmedStr[i] = string[start];
        i++; start++;
    }

    trimmedStr[i] = '\0';
    free(string);

    return trimmedStr;
}

Valgrind error:

==3809== Invalid read of size 1
==3809==    at 0x1090D5: trimString (myio.c:129)               
==3809==    by 0x109080: ReadLineFile(myio.c:120)
==3809==    by 0x108C54: main (driver2.c:29)
==3809==  Address 0x522e03e is 2 bytes before a block of size 16 alloc'd
==3809==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload/memcheck-amd64-linux.so)
==3809==    by 0x108F91: ReadLineFile(myio.c:90)
==3809==    by 0x108C54: main (driver2.c:29)

I expected valgrind to come out with not errors since I allocated enough memory in the strings but instead is telling me that I'm trying to access memory I'm not supposed to when I try to iterate the array backwards. I wish to understand what's causing this since I've spend multiple hours trying to figure out this error. Thanks!


Solution

  • What if the line is just spaces, or an empty line?

    In that case while(string[end-2] == ' '){end--;} might reach the beginning of the line and continue walking "backwards".

    Consider testing the limits of the line / string. Also, why -2? why not -1?i.e.:

    while(end > start && string[end - 1] == ' ') --end;
    

    This approach will protect you from "walking" too far back.

    Side-Note:

    The EOF marker isn't a valid byte (it isn't in the 0-255 value range). If it were, it might be a valid value in the middle of a file.

    For this reason, EOF can't be contained in a char you can't test if a char contains an EOF. Use int val instead of char val.