2

When I debug my PRJ I get this error:

args Error: Multiple errors reported.\ Failed to execute MI command: -var-create -

args Error message from debugger back end: Attempt to dereference a generic pointer.\ Unable to create variable object

the error comes when casting from void* args to Mapper* arg.

UPDATE 1

KMaster, KMapper implements respectively Master, Mapper but they do not add nothing rilevant. Effectively is KMapper that call the method work(). Here is the code:

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

Hope that someone can help!

UPDATE 2

Screenshot of the debugger:

eclipse debug

Community
  • 1
  • 1
Duccio B.
  • 77
  • 7
  • 1
    Why not `return pthread_create(&thread,NULL,start,reinterpret_cast(this));` – David Schwartz Jan 24 '13 at 20:16
  • 2
    @DavidSchwartz: No need. Just `this` will do. – Kerrek SB Jan 24 '13 at 20:18
  • Is `Mapper` a base class of a more-derived object? – Kerrek SB Jan 24 '13 at 20:18
  • If you use reinterpret_cast, you must use it both ways. If you just pass in the pointer and let it implicitly convert to void*, you should use static_cast. – Ulrich Eckhardt Jan 24 '13 at 20:19
  • probably duplicate of http://stackoverflow.com/q/310451/819272 – TemplateRex Jan 24 '13 at 20:21
  • 1
    BTW: Formally, `start` must be declared `extern "C"`, but it's unlikely that this causes your errors. – Ulrich Eckhardt Jan 24 '13 at 20:21
  • @KerrekSB: Mapper is a base-(pure)virtual class – Duccio B. Jan 24 '13 at 20:23
  • 1
    Why aren't you using `std::thread`? – Alex Chamberlain Jan 24 '13 at 20:23
  • @DuccioB. you can't create objects of abstract classes – TemplateRex Jan 24 '13 at 20:28
  • @DuccioB. Show us the class `Mapper` and the arguments you pass to `void* start(void* args)` – TemplateRex Jan 24 '13 at 20:35
  • @doomster: Can you explain that in more detail. Is the implicit cast to void* not a reinterpret_cast? A static_cast is for converting types that are similar. void* is not similar to anything (apart from its the generic pointer). – Martin York Jan 24 '13 at 20:35
  • Please can we have the complete definition of `Mapper`? – Alex Chamberlain Jan 24 '13 at 20:36
  • 1
    Are you sure you're casting to and from the same class? You're not casting back to a more-derived class by accident? – Kerrek SB Jan 24 '13 at 20:42
  • @KerrekSB: The code show shows starting as a Mapper* (as we are in `Mapper::work()`) and an explicit reinterpret_cast back to Mapper*. – Martin York Jan 24 '13 at 20:49
  • The error message seems a bit funny compared to the line that is generating it. There is no `object` creation here. Is this the exact code that you are running? – Martin York Jan 24 '13 at 20:50
  • @LokiAstari explicit reinterpret_cast to Mapper* will mess up inheritance because of things like offset into the vtable – TemplateRex Jan 24 '13 at 20:54
  • @rhalbersma there is nothing to mess up since the void* is created from a Mapper*. – R. Martinho Fernandes Jan 24 '13 at 21:03
  • @R.MartinhoFernandes Ok, so if args is being passed a derived class of an abstract base class Mapper, then dereferencing will be OK? – TemplateRex Jan 24 '13 at 21:07
  • Yes. Whatever adjustments need to be made to account for inheritance are done in the `Mapper* m = this;` line. – R. Martinho Fernandes Jan 24 '13 at 21:10
  • @rhalbersma: From n3376: 5.2.10 Reinterpret cast paragraph 7: Converting a prvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value. The result of any other such pointer conversion is unspecified. Here T1 is `Mapper*` and T2 is `void*` and the restrictions hold. Note: The conversion must be to/from the exact type (using a derived type would break it). – Martin York Jan 24 '13 at 21:52
  • @LokiAstari Thanks for quoting the reinterpret_cast section. – TemplateRex Jan 24 '13 at 21:53
  • i've posted all the code that i'm running. the error is here (and is ready to kill all your programs). xD – Duccio B. Jan 24 '13 at 22:02
  • @LokiAstari: Note: The conversion must be to/from the exact type (using a derived type would break it) does it mean that if is KMapper that call work() the cast dows not work? – Duccio B. Jan 24 '13 at 22:11
  • Welcome to Stack Overflow! This discussion is growing too long and hard to follow. However it contains good information which should be integrated into the the question or an answer. Please do that and if needed, continue the discussion in the chat! – markus Jan 24 '13 at 23:04
  • @DuccioB. It should work. Because in `work()` the `this` pointer is a `Mapper*` (Because work() is a member of Mapper). – Martin York Jan 25 '13 at 01:35

1 Answers1

0

The value of arg is 24, which no normal object would live at, so the casting has nothing whatsoever to do with this.

Unfortunately, this "answer" can only be a wild guess because you haven't shown the calling code.

If arg is always 24, I would check for something similar to this:

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.

It's also possible that you have an uninitialised variable

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

which just happens to be 24.

molbdnilo
  • 64,751
  • 3
  • 43
  • 82
  • could it be that i'm using a pthread wrapper class (the base-class Mapper or the derived class KMapper contains an attribute pthread_t thread) and i'm passing "this" as pthread arguments? – Duccio B. Jan 24 '13 at 22:06
  • @DuccioB. That shouldn't matter. First, add a return statement to `start`. Missing one leads to undefined behaviour, which makes the entire program undefined (i.e. formally, the behaviour you're seeing is "normal"). Next, verify that `this` has a reasonable value inside `work`. And make sure that you're not overriding `work` in `KMapper` by mistake. After that, I have no idea. – molbdnilo Jan 25 '13 at 08:45
  • about ur answer i've seen that is args (the parameter to the thread function) that arrive with some errors. arg (that is a pointer to a Mapper object) point to args and i think this the reason because arg is 24 (arg point to nothig). am i right? – Duccio B. Jan 25 '13 at 09:13
  • @DuccioB. `arg` is exactly the same bits as `args`, just reinterpreted ("reinterpret_cast") as a `Mapper*` rather than a `void*`. They will have the same value (24). What your cast does is making a promise to the compiler that `args` is *actually* a `Mapper*` and asking it to treat it as one of those instead. If you really passed it something else, like a `KMapper*`, all bets are off. – molbdnilo Jan 25 '13 at 10:27