valgrind - адрес составляет 2 байта, прежде чем выделится блок размером 16 - PullRequest
0 голосов
/ 20 января 2019

У меня возникла небольшая проблема, пытавшаяся понять, почему Вальгринд говорит мне, что я выхожу за пределы массива char *.

Всякий раз, когда я пытаюсь выполнить итерацию массива в обратном порядке, начиная с нулевого байта. Это выдает ошибку, что я обращаюсь к памяти, которую я не должен.

Это моя первая функция:

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);
}

Это моя вторая функция:

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:

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

Я ожидал, что valgrind выйдет без ошибок, так как я выделил достаточно памяти в строках, но вместо этого говорит мне, что я пытаюсь получить доступ к памяти, которую я не должен делать, когда пытаюсь выполнить итерацию массива в обратном направлении. Я хочу понять, что является причиной этого, так как я потратил несколько часов, пытаясь выяснить эту ошибку. Спасибо!

1 Ответ

0 голосов
/ 20 января 2019

Что делать, если строка является просто пробелами или пустой строкой?

В этом случае while(string[end-2] == ' '){end--;} может достичь начала строки и продолжить идти "назад".

Рассмотрите возможность тестированияпределы строки / строки.Кроме того, почему -2?почему бы не -1? то есть:

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

Этот подход защитит вас от "ходьбы" слишком далеко назад.

Примечание :

Маркер EOF не является допустимым байтом (он не находится в диапазоне значений 0-255).В противном случае это может быть допустимое значение в середине файла.

По этой причине EOF не может содержаться в char, вы не можете проверить, содержит ли charEOF.Используйте int val вместо char val.

...