Получение ошибки сегментации в C при использовании сна с Pthreads - PullRequest
0 голосов
/ 09 ноября 2018

Я создаю поток в C с PThreads, который выполняет функцию, которая выполняется в бесконечном цикле и печатает некоторую случайную строку json каждую секунду в консоль. Сначала он печатает результат функции simulateLED без проблем, но после 1 секунды сна я получу ошибку сегментации (ядро сброшено). Если я уберу сон, я его не получу и программа работает нормально. Почему я получаю ошибку сегментации со сном и как ее исправить?

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

char *simulateLED() {
    int temp;
    int luftf;
    char* jsonString;

    time_t t;
    srand((unsigned) time(&t));

    int x=-10, y=50;
    temp=(rand()%((y+1)-x))+x;

    x=2, y=30;
    luftf=(rand()%((y+1)-x))+x;

    printf("%d %d\n", temp, luftf);
    fflush(stdout);

    sprintf(jsonString, "{\n\"TEMP\": %d,\n\"HUMI\": %d\n}", temp, luftf);

    return jsonString;
}
void *simAndSendThread(void *param) {
    while(1) {
        printf("%s", simulateLED());
        sleep(1);
    }
}
int main(int argc, char *argv[]) {
    pthread_t thread;

    if(pthread_create(&thread, NULL, simAndSendThread, NULL)) {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }

    if(pthread_join(thread, NULL)) {
        fprintf(stderr, "Error joining thread\n");
        return 2;
    }

    pthread_exit(NULL);
    return 0;
}

Ответы [ 2 ]

0 голосов
/ 09 ноября 2018

Как указал @DavidSchwartz, причина ошибки Segmentation fault (core dumped) связана с указателем jsonString, который в данный момент не инициализирован (то есть не , указывающим на что-либо). Следовательно, sprintf пишет в случайное место, которое может работать или не работать время от времени.

Чтобы исправить это, вы можете статически назначить пространство переменной jsonString при ее объявлении, например:

...
char jsonString[256];
...

Это означает, что вы можете иметь строку длиной до 255 символов (1 дополнительный символ, зарезервированный для \0). Кроме того, вы можете динамически распределять пространство, используя malloc:

...
char *jsonString = (char *)malloc(sizeof(char) * 256);

// Your code here

free(jsonString);
...

В этом случае вы должны не забыть освободить выделение в конце вашей функции, используя free, иначе вы потеряете память. Если вы еще не узнали о динамической памяти, см. Когда и зачем использовать malloc? .

P.S .: Если вы работаете в Linux, я настоятельно рекомендую использовать valgrind, если у вас есть ошибки, связанные с памятью. Этот инструмент, скорее всего, подскажет, где вы допустили ошибку. Обратитесь к Краткое руководство Valgrind для получения дополнительной информации.

0 голосов
/ 09 ноября 2018

Вы не выделили память для jsonString и все еще пытаетесь выполнить sprintf и после возврата print

Попробуйте это

char* jsonString;
    jsonString = malloc( 1024 );

И не забудьте free, как только вы закончите, вы используете while(1), а если вы не free, есть все шансы, что вы попадете в из памяти ошибка очень скоро.

Если вы enable full warnings, вы должны были получить warning message for uninitialized variable, за который в конечном итоге избежали бы всех сбоев.

...