MoeMan
MoeMan

Reputation: 49

Passing struct data arguments to threads

I'm confused on how to pass struct arguments to threads in the for loop.

When I try with this approach, I get garbage port values. When I try to change the struct to just astruct argstruct; without the pointer, the second port overwrites the first one so I get 200 200 printed.

Also, would I have to free the struct in main, Func, or both?

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
void* Func(void* pstruct);

typedef struct thread_args{
    int port;
} astruct;

int main()
{
    int peers[2] = {100,200};
    pthread_t threads[2];
    astruct *argstruct[2];
    for (int i = 0; i < 2; i++) {
        argstruct[i] = malloc(sizeof(astruct));
        argstruct[i]->port = peers[i];
        pthread_create(&threads[i],NULL,Func,&argstruct[i]);
    }
    for(int i = 0; i < 2; i++){
        pthread_join(threads[i], NULL);
    }

    return 0;
}

void* Func(void* pstruct){
    int port;
    astruct *argstruct = (astruct *)pstruct;
    
    port = argstruct->port;
    printf("port: %d\n", port);
    return 0;
}

Upvotes: 1

Views: 46

Answers (1)

anastaciu
anastaciu

Reputation: 23832

I'm confused on how to pass struct arguments to threads in the for loop.

argstruct[i] elements are pointers, you don't need address operator:

pthread_create(&threads[i], NULL, Func, argstruct[i]);

Note that you wouldn't need memory allocation for this simple case, you can use a local array:

//...
astruct argstruct[2];
for (int i = 0; i < 2; i++) {   
    argstruct[i].port = peers[i];
    pthread_create(&threads[i], NULL, Func, &argstruct[i]);
}
//...

Also, would I have to free the struct in main, Func, or both?

You should free it one time only. The procedure is always the same, you free it when you don't need it anymore, that can be in the the thread routine or in main.

In your example, you could very well free the memory after port = argstruct->port; as you no longer use it after this assignment:

void* Func(void* pstruct){
    int port;
    astruct *argstruct = (astruct *)pstruct;
    
    port = argstruct->port;
    free(argstruct); //<-- here
    printf("port: %d\n", port);
    return 0;
}

Upvotes: 2

Related Questions