0

我遇到了一个似乎很奇怪的问题,但这可能是 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. 但是,如果它实际上设置为NULL它永远不会进入该 if 块开始。在调试器中,我看到 的地址与BlahqDebug() << "toDelete: " << toDelete;在设置toDelete = NULL;.

TLDR;在我删除指针并将相同的指针设置为NULL. 由于指针未NULL在执行的后期设置,因此会导致崩溃。

4

2 回答 2

3

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

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

toDelete2 & toDelete3 仍将指向原始对象

而不是在删除后使指针为空,您应该将其从映射中删除或将该键的值设置为 NULL。

于 2013-01-15T15:23:10.523 回答
2
someType* toDelete = mySomeTypeMap.take(key);

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

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

mySomeTypeMap.insert(key, 0);
于 2013-01-15T15:36:26.833 回答