我有一个我正在尝试实现的小型Thread类的以下代码片段:
声明:
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();
知道为什么代码段错误?我记得指向成员函数的指针在转换为void *并返回时并不是很好。是这样的情况(因为我不直接这样做)?
任何指针/建议都将受到高度赞赏。
谢谢! :)
答案 0 :(得分:1)
这是segfaulting,因为在调用createThread函数之前,临时对std::pair<T*, void (T::*)()> p(arg,function);
正在从范围上掉下来。
将对的副本存储在堆内存中并传递。 然后删除createThread函数中的副本。
修改强>
顺便说一下,使用std :: functions可能会更好地表示。完全相同的想法(代码甚至看起来相似),但不会强迫您重写代码以获取其他参数。请看pthread member function of a class with arguments。