user1103651
user1103651

Reputation: 13

Binding pointer-to-member-function to std::pair and casting to void*

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

Answers (1)

user406009
user406009

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

Related Questions