Search code examples
csegmentation-faultpthreadssleep

Getting Segmentation Fault in C when using sleep with Pthreads


I am creating a thread in C with PThreads which executes a function that is running in an infinit loop and prints some random json string every second into the console. At the beginning he prints the result of the function simulateLED with no problem, but after sleeping for 1 second, I'll get a Segmentation Fault (Core dumped). If I remove sleep, I'll not get it and the program works fine. Why do I get a Segmentation Fault with sleeping and how to fix it?

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

Solution

  • As @DavidSchwartz has pointed out, the reason for the Segmentation fault (core dumped) error is related to the jsonString pointer, that is currently not initialized (i.e., not pointing to anything). Hence, sprintf is writing to a random location, which might or might not work at times.

    In order to fix it, you can statically assign space to the jsonString variable when you declare it, such as:

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

    This implies that you can have a string up to 255 characters (1 extra character reserved for \0). Alternatively, you can dynamically allocate the space using malloc:

    ...
    char *jsonString = (char *)malloc(sizeof(char) * 256);
    
    // Your code here
    
    free(jsonString);
    ...
    

    In this case, you must remember to release the allocation at the end of your function using free, otherwise you will leak memory. In case you haven't learned about dynamic memory yet, see When and why to use malloc?.

    P.S.: If you are on Linux, I strongly recommend to use valgrind when you have memory-related errors. This tool will most probably hint where did you made the mistake. Check the Valgrind Quick Start Guide for more information.