Matt Hough
Matt Hough

Reputation: 1101

Struct data passed into pthread_create is incorrect when read

In the below code I am trying to pass a struct into pthread_create. The struct is defined globally. It is then initialized before calling pthread_create.

// Global scope
struct dat_struct {
  char *dat[SIZE];
  int received[SIZE];
  int numreceived;
};

 // main
  struct dat_struct *data = malloc(sizeof(struct dat_struct));


  for (int i=0; i < nthreads; i++) {
    for (int j=0; j < SIZE; j++) {
      data->received[j] = SIZE;
    }
    data->numreceived = 0;
    pthread_create(&thread_ids[i], NULL, thread_handler, (void*)&data);
  }

void *thread_handler(void *dat) {
  struct dat_struct *data = (struct dat*)dat;
  // If I read data->numreceived it returns a large negative or
  // something incorrect
  ...
  ...

In thread_handler, reading the data gives incorrect results. If I use gdb to check what is passed into pthread_create, it is different to what is being received on the other end.

Is there a fundamental issue in my code?

Upvotes: 0

Views: 37

Answers (1)

Andrew Henle
Andrew Henle

Reputation: 1

Given

struct dat_struct *data

This code

pthread_create(&thread_ids[i], NULL, thread_handler, (void*)&data);

passes a struct dat_struct ** to the thread as a void *. Note the double **.

Thus this is wrong:

void *thread_handler(void *dat) {
  struct dat_struct *data = (struct dat*)dat;

That code treats dat as a struct dat_struct * - but you passed a struct dat_struct **. (I'm assuming the (struct dat*) is a typographical error).

You should create the thread with

pthread_create(&thread_ids[i], NULL, thread_handler, data);

and

void *thread_handler(void *dat) {
  struct dat_struct *data = dat;

Note that there is no need to cast to/from void * in C.

Upvotes: 1

Related Questions