使QMap内的指针值无效

时间:2013-01-15 15:11:00

标签: c++ qt pointers memory-management qmap

我有一个似乎是一个奇怪的问题,但它可能是QMap的工作方式的一个怪癖,我只是不理解它。总结这个问题很难,但我会尽我所能。

我有一个A课,QMap<QString, someType*> mySomeTypeMap;。当我在程序中加载新文件时,我想删除此QMap的所有内容,以便我可以使用新数据重新填充它。我通过以下方式做到这一点:

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

qDebug()语句打印出我要删除的值的正确地址,当我在设置为toDelete后查看调试器中的NULL时,它会显示0x0 ,这就是我想要的。

然后,在另一个班级B中,我有以下代码......

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

        Blah = blah;

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

现在,真正令人困惑的是我的程序在到达disconnectAllSignals();行时崩溃了。原因是它试图在disconnect()上调用已被删除的Blah,当我将其设置为NULL时应将其设置为0x0。但是,如果它实际上设置为NULL,它就永远不会输入if-block。在调试器中,我发现Blah的地址与我在设置qDebug() << "toDelete: " << toDelete;之前打印toDelete = NULL;时的地址完全相同。

TLDR;在删除指针并将同一指针设置为NULL后,我不知道我的程序如何获取指针的原始地址。由于指针在执行后期未设置为NULL,因此会导致崩溃。

2 个答案:

答案 0 :(得分:3)

映射中的值按值存储,即使在这种情况下,它意味着指针(它指向的地址)按值存储。 例如:

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

toDelete2&amp; toDelete3仍将指向原始对象

除了在删除后使指针为空,您应该将其从地图中删除或将该键的值设置为NULL。

答案 1 :(得分:2)

someType* toDelete = mySomeTypeMap.take(key);

这是在堆栈上创建的指针变量,其值设置为您在map中保留的值。你不需要将它设置为NULL,因为它会立即超出范围。

take函数正在从地图中删除指针,如果再次使用相同的键,它将返回默认构造的值。在delete尝试

之后
mySomeTypeMap.insert(key, 0);