【问题标题】:Pthread and void* attempt to de-reference a generic pointerPthread 和 void* 尝试取消引用泛型指针
【发布时间】:2013-01-08 17:09:04
【问题描述】:

当我调试我的prj时,我收到此错误:

args 错误:报告多个错误。\ 执行 MI 命令失败:-var-create -

来自调试器后端的args 错误消息:尝试取消引用通用指针。\ 无法创建变量对象

从 void* args 转换为 Mapper* arg 时出现错误。

更新 1

KMaster、KMapper 分别实现了 Master、Mapper 但它们并没有添加任何相关的内容。有效地是致电方法work()的kmapper。代码如下:

int main(){
    int np=1,K=4;
    string path="lucca.gps";
    KMaster* master=new KMaster(path,np,K);
    KMapper* mapper[np];
    master->splitting();
    for(int i=0;i<np;i++){
            mapper[i]=new KMapper(master,master->mData[i].key,master->mData[i].value);
            while(mapper[i]->work()!=0){
                cout<<"failed creating mapper, retry..."<<endl;
                sleep(1000);
            }
    }
}

int KMaster::splitting(){
    cout<<"start splitting"<<endl;
    fstream is(path.c_str());
    string s="";
    getline(is,s);
    while(!is.eof()){
        for(int i=0;i<nProc;i++){
            pair<double,double> res;
            is>>res.first;
            is>>res.second;
            is>>s;
            mapData[i].push_back(res);
            Data.push_back(res);
            if(is.eof()) break;
        }
    }        
    list<pair<double,double> >::iterator it=Data.begin();
    int increment=Data.size()/K;
    for(int i=0;i<K;i++){
        Klusters.push_back(*it);
        advance(it,increment);
    }
    for(int i=0;i<nProc;i++){
        mData[i].key=&Klusters;
        mData[i].value=&mapData[i];
    }
    cout<<"splitting completed"<<endl;
    return 0;
}

int Mapper::work(){
    Mapper* m=this;
    void* p=m;
    return pthread_create(&thread,NULL,start,p);
}

void* start(void* args){
    cout<<"start()"<<endl;
    Mapper* arg= reinterpret_cast<Mapper*>(args);
    arg->mapResult=arg->map(arg->k,arg->v);
    cout<<"Mapper finish, sending result..."<<endl;
    arg->send(arg->mapResult);
}

希望有人能帮忙!

更新 2

调试器截图:

【问题讨论】:

  • 为什么不return pthread_create(&amp;thread,NULL,start,reinterpret_cast&lt;void *&gt;(this)); span>
  • @ davidschwartz:无需。只需this 即可。
  • 顺便说一句:形式上,start 必须声明为extern "C",但这不太可能导致您的错误。
  • 你为什么不用std::thread
  • 您确定要在同一个班级进行投射吗?您不会意外地退回到派生度更高的类吗?

标签: c++ void-pointers reinterpret-cast static-cast


【解决方案1】:

arg 的值是 24,没有正常的对象会存在,因此强制转换与此无关。

不幸的是,这个“答案”只能是一个疯狂的猜测,因为你没有显示调用代码。

如果arg 总是 24,我会检查类似的内容:

class Something
{
public:
    void dostuff() { mapper.work(); }
private:
    // 24 bytes of "stuff" before this member (including possibly a vtable)
    Mapper mapper;
};

Something *thing = 0;
thing->dostuff(); // Thing->mapper will have address 24.

也有可能你有一个未初始化的变量

Mapper* mapper;
mapper->work(); // Oops, uninitialised

恰好是 24 岁。

【讨论】:

  • 可能是我正在使用 pthread 包装类(基类 Mapper 或派生类 KMapper 包含属性 pthread_t 线程)并且我将“this”作为 pthread 参数传递?
  • @DuccioB。那应该没关系。首先,在start 中添加return 语句。缺少一个会导致未定义的行为,从而使整个程序未定义(即正式地,您看到的行为是“正常的”)。接下来,验证thiswork 中的值是否合理。并确保您没有错误地在KMapper 中覆盖work。之后,我就不知道了。
  • 关于你的答案,我看到的是 args(线程函数的参数),它带有一些错误。 arg(即指向 Mapper 对象的指针)指向 args,我认为这是原因,因为 arg 是 24(arg 指向 nothig)。我说的对吗?
  • @DuccioB。 argargs 完全相同,只是重新解释(“reinterpret_cast”)为 Mapper* 而不是 void*。它们将具有相同的值 (24)。你的演员所做的是向编译器承诺args实际上Mapper*,并要求它将其视为其中之一。如果你真的通过了别的东西,比如KMapper*,那么所有的赌注都没有了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-17
  • 2016-04-16
  • 2013-02-21
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多