我有一个似乎是一个奇怪的问题,但它可能是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
,因此会导致崩溃。
答案 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);