Question

I'm having what seems to be a weird issue, but it could be a quirk of how QMap's work and I just don't understand it. It's tough to summarize the problem, but I'll do my best.

I have a class A, with a QMap<QString, someType*> mySomeTypeMap;. When I load a new file in my program, I want to delete all the contents of this QMap so I can repopulate it with new data. I do that by doing the following:

foreach (QString key, mySomeTypeMap.keys())
{
    someType* toDelete = mySomeTypeMap.take(key);

    //Show me the original address of the pointer
    qDebug() << "toDelete: " << toDelete;

    delete toDelete;

    //Set the pointer to 0x0
    toDelete = NULL;
}

The qDebug() statement prints out the correct address of the value I want to delete, and when I look at toDelete in the debugger after it gets set to NULL, it says 0x0, which is what I want.

Then later, in a different class B, I have the following code...

void B::setSomeType(someType* blah)
{
    if (Blah != NULL)
    {
        //Calls a bunch of disconnect()'s
        disconnectAllSignals();

        Blah = blah;

        //Calls a bunch of connect()'s
        connectAllSignals();
    }
}

Now, what's really confusing is my program crashes when it gets to the disconnectAllSignals(); line. The reason being it's trying to call disconnect() on Blah which was deleted and should have been set to 0x0 when I set it to NULL. However, if it was actually set to NULL it never would have entered that if-block to begin with. In a debugger, I see that the address of Blah is exactly the same as what I get when I print out qDebug() << "toDelete: " << toDelete; right before setting toDelete = NULL;.

TLDR; I don't know how my program is getting the orignal address of a pointer back after I delete the pointer and set the same pointer to NULL. Since the pointer isn't set to NULL later in the execution it leads to a crash.

Was it helpful?

Solution

Values in the map are stored by value even if in these case it means that the pointer (address which it points) is stored by value. For example:

someType* toDelete1 = mySomeTypeMap.take(key);
someType* toDelete2 = mySomeTypeMap.take(key);
someType* toDelete3 = toDelete1;
toDelete1 = NULL;

toDelete2 & toDelete3 will still point to the original object

Instead of making the pointer null after delete you should either remove it from the map or set the value for that key to NULL.

OTHER TIPS

someType* toDelete = mySomeTypeMap.take(key);

This is a pointer variable created on stack and its value is set to the value that you keep in map. You dont need to set it to NULL, because it goes out of scope right away.

take function is removing pointer from the map, if you use it again with the same key it will return default-constructed value. Just after delete try to

mySomeTypeMap.insert(key, 0);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top