I need to pass a structure to a pthread and be able to change the values of the struct from the function the pthread will execute. This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <pthread.h>
void *deal_cards(void* deck);
int main() {
struct t_data {
std::string name;
std::string status;
std::vector<int> hand;
std::vector<int> *ptr_deck;
};
std::vector<int> deck = {1,2,3};
std::vector<int> *p_deck = &deck;
struct t_data player1_data = {"PLAYER 1", "lose", {}, p_deck};
struct t_data *player1 = &player1_data;
pthread_t p1;
pthread_create (&p1, NULL, deal_cards, (void *) player1);
}
void* deal_cards (void* data) {
(struct t_data*)->(std::vector<int>*)ptr_deck.push_back(3);
}
I get the following error when I run this
In function 'void* deal_cards (void*)
error: expected primary-expression before 'struct'
error: expected ')' before 'struct'
In case it matters I'm compiling on Linux with
g main.cpp -o main -lpthreads
What am I missing and is that the right way to alter the values inside the structure?
CodePudding user response:
There are numerous mistakes in your code:
The
t_data
structure type is defined local tomain()
, sodeal_cards()
can't use it.main()
is exiting, destroying its local variables, while the thread is still running.the syntax you are trying to use to access
push_back()
indeal_cards()
is all wrong. You are not referencing thedata
input parameter at all, that is what you should be type-casting tot_data*
. And, you are type-castingptr_deck
tostd::vector<int>*
, which it is already typed as, so that cast is unnecessary. And, sinceptr_deck
is a pointer, you need to use the->
operator to access itspush_back()
method, not the.
operator.
Also, while not strictly errors, you should also be aware of these:
you are using
std::string
without#include <string>
unlike in C, in C you don't need to prefix references to a structure type with the
struct
keyword. Only the declaration of the structure type needs to use thestruct
keyword.
With that said, try this instead:
#include <vector>
#include <string>
#include <pthread.h>
void* deal_cards(void* deck);
struct t_data {
std::string name;
std::string status;
std::vector<int> hand;
std::vector<int> *ptr_deck;
};
int main() {
std::vector<int> deck = {1,2,3};
t_data player1_data = {"PLAYER 1", "lose", {}, &deck};
pthread_t p1;
if (pthread_create (&p1, NULL, deal_cards, &player1_data) == 0) {
pthread_join (p1, NULL);
// use deck as needed...
}
}
void* deal_cards (void* data) {
static_cast<t_data*>(data)->ptr_deck->push_back(3);
return NULL;
}
Though, you really should be using C 's own std::thread
class instead of pthreads directly:
#include <vector>
#include <string>
#include <thread>
struct t_data {
std::string name;
std::string status;
std::vector<int> hand;
std::vector<int> *ptr_deck;
};
void deal_cards(t_data* deck);
int main() {
std::vector<int> deck = {1,2,3};
t_data player1_data = {"PLAYER 1", "lose", {}, &deck};
std::thread p1(deal_cards, &player1_data);
p1.join();
// use deck as needed...
}
void deal_cards (t_data* data) {
data->ptr_deck->push_back(3);
}