Valgrind: Неверное чтение размера 1 (strtok, atoi) - PullRequest
0 голосов
/ 30 марта 2020

У меня проблема с valgrind: это моя программа (ну, основная часть, где появляются ошибки):

static void leerLinea(u32 *a, u32 *b, FILE *file) {
    char *linea = NULL;
    char *token = NULL;

    linea = readline(file);
    token = strtok(linea, " ");
    free(linea);
    linea = NULL;
    while (!strcmp(token, "c")) {
        linea = readline(file);
        token = strtok(linea, " ");
        free(linea);
        linea = NULL;
    }

    if (!strcmp(token, "p")) {
        token = strtok(NULL, " ");
        token = strtok(NULL, " ");
        *a = atoi(token);
        token = strtok(NULL, " ");
        *b = atoi(token);
    } else if (!strcmp(token, "e")) {
        token = strtok(NULL, " ");
        *a = atoi(token);
        token = strtok(NULL, " ");
        *b = atoi(token);
    }
}

И когда я запускаю valgrind, он говорит:

Invalid read of size 1
at 0x4905E72: strtok_r (strtok_r.c:49)
Address 0x4a42b12 is 2 bytes inside a block of size 128 free'd

Я не могу понять, что случилось с этой программой.

1 Ответ

3 голосов
/ 30 марта 2020

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

Вы можете попробовать что-то вроде этого (не проверено):

static void leerLinea(u32 *a, u32 *b, FILE *file) {
    char *linea = NULL;
    char *token = NULL;

    linea = readline(file);
    token = strtok(linea, " ");

    while (!strcmp(token, "c")) {
        free(linea);
        linea = readline(file);
        token = strtok(linea, " ");
    }

    if (!strcmp(token, "p")) {
        token = strtok(NULL, " ");
        token = strtok(NULL, " ");
        *a = atoi(token);
        token = strtok(NULL, " ");
        *b = atoi(token);
    } else if (!strcmp(token, "e")) {
        token = strtok(NULL, " ");
        *a = atoi(token);
        token = strtok(NULL, " ");
        *b = atoi(token);
    }
    free(linea);
}

Примечание. Этот код не включает никаких проверок для возвращаемые значения так же, как это только демонстрирует, как изменить код из вопроса.

Возвращаемое значение strtok должно проверяться на NULL значения перед подачей в atoi или другие функции, чтобы избежать неопределенного поведения

...