2011-12-17 5 views
1

私は私が実装しようとしている小さなThreadクラスの次のコードスニペットがありますバインディングへのポインタメンバ関数はstdする::ペアと無効にキャスト*

宣言:

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; 
}; 

以下は定義のスニペットです。上記のコードで

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); 
} 

Temp機能およびフィールド 'A' を持つクラスです。スレッドは次のコードで実行されます。

Temp t; 
t.a=11; 
Thread<Temp> tt(&t, &Temp::function); 

tt.start(); 

なぜコードがsegfaultsなのでしょうか?メンバ関数へのポインタがvoid *へのキャストと実際にうまくいっていないことを思い出します。それはここにあるのですか(私はそれを直接行っていないからです)?

どのようなポインタ/提案も高く評価されます。

ありがとうございます! :)

答えて

1

一時的なペアstd::pair<T*, void (T::*)()> p(arg,function);がcreateThread関数が呼び出される前にスコープから外れているため、segfaultingです。

ヒープメモリにペアのコピーを保存して渡します。 次に、createThread関数内のコピーを削除します。さておき、これはおそらくより良いのstd ::関数を用いて表現されるように

EDIT

。まったく同じアイデア(コードも同じように見えます)が、追加の引数のためにコードを書き直す必要はありません。 pthread member function of a class with argumentsをご覧ください。

+0

どうしたことがありますか?私はそれをあきらめるために私の心の外だった! :P ありがとうイーサン、おかげでトン! :) – user1103651

+1

@ user1103651 pthread_createに引数をバインドしようとしたときと全く同じ間違いを犯しました。誰もがC++でセグメンテーションを持っています。 – Lalaland

関連する問題