Ajk
Ajk

Reputation: 31

About malloc behavior in pthread

My program is divided into 2 parts:

  1. The library file (libprog.c), with only one function:

    int *
    libfunc(void)
    {
        int     *i;
    
        i = malloc (sizeof(int));
    
        printf("in lib, %d\n", *i);
        return i;
    }
    
  2. The main program (prog.c):

    void *
    thr_func(void *arg)
    {
        int     *p;
    
        p = libfunc();
        printf("in thr: %d\n", *p);
    
        return (void *)0;
    }
    
    int
    main(int argc, char **argv)
    {
        pthread_t       tid;
    
        pthread_create(&tid, NULL, thr_func, NULL);
        pthread_join(tid, NULL);
    
        return 0;
    }
    

As you can see, I'm just creating one pthread and passing thr_func() function to it which in turn calls libfunc(), which allocates one integer using malloc() and returns its pointer. When I run this program, it prints the integer i in libfunc(), but gives segmentation fault when I try to access it in thr_func(), it gives segfault:

bash-4.1$ ./prog
in lib, 0
Segmentation fault (core dumped)

But when I remove the thread creation using pthread and call thr_func() directly in main(), the program runs successfully:

bash-4.1$ ./prog
in lib, 0
in thr: 0

So how is pthread affecting the way memory is accessed here? What should I do to make it work?

Upvotes: 1

Views: 885

Answers (1)

Sander De Dycker
Sander De Dycker

Reputation: 16243

The problem is that your prog.c compilation unit doesn't see a declaration for the libfunc function. So, the following (default) declaration is used instead :

int libfunc();

Note that this is different from the real one :

int* libfunc();

Now, when libfunc is called from thr_func, the returned int* pointer is interpreted as an int, and then cast back to an int* when storing it in the local p variable. The result of casting an int to a pointer type is implementation defined. On your platform, this resulted in a messed up pointer value, which ended up causing a segmentation fault.

To fix this, add the following line to the top of prog.c :

int* libfunc();

Or better yet, create a proper header file that goes with libprog.c.

Upvotes: 1

Related Questions