Reputation: 13
I have the following code snippet of a small Thread class I am trying to implement:
declaration:
template <typename T>
class Thread{
public:
Thread(T*, void (T::*)());
void start();
private:
friend void* createThread(void*);
T* arg; //the object
void (T::*function)(); //the ptr to function in that object of type T
pthread_t thread;
};
And below is a snippet of the definition.
template <typename T>
void* createThread(void *arg){
//get back the pair..
std::pair<T*, void (T::*)()>* p = (std::pair<T*, void (T::*)()>*)arg;
//open up the pair
T& t = *p->first;
void (T::*fn)() = p->second;
//TEST
Temp ttt;
ttt.a=100;
(ttt.*fn)(); //segfaults here..
(t.*fn)(); //and even here
}
template <typename T>
void Thread<T>::start(){
//pair of pointer to object, and the pointer-to-member-function
std::pair<T*, void (T::*)()> p(arg,function);
pthread_create(&thread, NULL, createThread<T>, (void*)&p);
}
In the above code, Temp
is a class with a function and a field 'a'. And I get the thread running by the following code:
Temp t;
t.a=11;
Thread<Temp> tt(&t, &Temp::function);
tt.start();
Any idea why the code segfaults? I recollect that pointer-to-member-function does not really go well with casting to void* and back. Is that the case in here (since I am not doing that directly)?
Any pointers/suggestions will be highly appreciated.
Thanks! :)
Upvotes: 1
Views: 1203
Reputation:
It is segfaulting because your temporary pair std::pair<T*, void (T::*)()> p(arg,function);
is falling off the scope before your createThread function is called.
Store a copy of your pair in a heap memory and pass that. Then delete the copy inside the createThread function.
EDIT
As an aside, this would probably be better represented using std::functions. Exactly same idea(code even looks similar), but does not force you to rewrite your code for additional arguments. Look at pthread member function of a class with arguments.
Upvotes: 1