Ошибка сегментации при использовании nanosleep()

#c #types #sleep #long-integer #time.h

Вопрос:

 $ ls
baby.txt      readlyrics.c
 

Я попытался написать простую программу для печати текста из файла .txt с помощью nanosleep (), чтобы получить какой-то анимированный эффект:

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


int main(int argc, char *argv[]) {

    char *target_file = argv[1];
    char *sec     = argv[2];
    char *nsec     = argv[3];

    int   tv_sec  = atoi(sec);
    float tv_nsec = atof(nsec);

    struct timespec *t;
    t->tv_sec  = tv_sec;
    t->tv_nsec = (long)(tv_nsec * 1000000000);

    FILE *content = fopen(target_file, "r");
    int *c  = malloc(sizeof(char));
    c       = NULL;
    c = fgetc(content);
    while(c) {
        printf("%c", c);
        c = NULL;
        nanosleep(t, NULL);
        c = fgetc(content);
    }
    fclose(content);

    return 0;
}

 

И получил ошибку:

 $ ./read ./baby.txt 0 0.01
zsh: segmentation fault  ./read ./baby.txt 0 0.01
 

Какая часть кода пошла не так?

Комментарии:

1. Сборка с отладочной информацией (добавьте -g флаг при сборке). Затем запустите отладчик, чтобы зафиксировать сбой и точно определить, где в вашем коде это происходит. Затем вы также можете изучить переменные и их значения, чтобы узнать, дают ли они какие-либо подсказки.

2. Кстати, все ваши fidling С c , что делает его указателем, и всех его назначений, а затем рассматривая ее как реальной char , а не указатель на один, что говорит мне, что нужно больше времени проводить с вашим текстом-книг об указателях, и, что более важно, почитайте про fgetc и что он возвращает. Похоже, у вас есть какое-то базовое недопонимание относительно чтения символов из файлов.

3. while(c) это неправильно. fgetc не возвращается 0 или NULL в конце файла. Вам нужно объявить c как int и сравнить с EOF ним . Обратите внимание, что EOF это обычно определяется как -1 и, следовательно, принимает значение true при использовании в логическом условии.

Ответ №1:

Думаю, теперь я знаю ответ… Помимо переменной c, я объявил t как указатель, и он не был инициализирован, после изменения struct timespec * на struct timespec Я решил проблему. Я думаю, это потому, что он полагается на ввод пользователя для инициализации.

Комментарии:

1. Вся эта неразбериха с c затенением заключается в том, что вы используете указатель t , не указывая его куда-либо. Но эту проблему можно было бы решить, включив больше предупреждений при сборке, поскольку GCC обычно способен улавливать такие проблемы.