C++ 使QMap内的指针值无效

C++ 使QMap内的指针值无效,c++,qt,pointers,memory-management,qmap,C++,Qt,Pointers,Memory Management,Qmap,我有一个似乎很奇怪的问题,但这可能是QMap如何工作的一个怪癖,我只是不明白。总结这个问题很难,但我会尽力的 我有一个类a,带有QMap-mySomeTypeMap。当我在程序中加载一个新文件时,我想删除这个QMap的所有内容,以便用新数据重新填充它。我通过执行以下操作来实现这一点: foreach (QString key, mySomeTypeMap.keys()) { someType* toDelete = mySomeTypeMap.take(key); //Show

我有一个似乎很奇怪的问题,但这可能是QMap如何工作的一个怪癖,我只是不明白。总结这个问题很难,但我会尽力的

我有一个类
a
,带有
QMap-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;
}

现在,真正令人困惑的是我的程序在到达
disconnectAllSignals()时崩溃行。原因是它试图调用
Blah上的
disconnect()
,该文件已被删除,当我将其设置为
NULL
时,应将其设置为0x0。然而,如果它实际上被设置为
NULL
,它就永远不会输入以该if块开头的内容。在调试器中,我看到
Blah
的地址与我打印地图中
qDebug()值时得到的地址完全相同,即使在这种情况下这意味着指针(它指向的地址)是按值存储的。
例如:

someType* toDelete1 = mySomeTypeMap.take(key);
someType* toDelete2 = mySomeTypeMap.take(key);
someType* toDelete3 = toDelete1;
toDelete1 = NULL;
toDelete2和toDelete3仍将指向原始对象


删除后,不应将指针设为null,而应将其从映射中删除或将该键的值设为null。

映射中的值是按值存储的,即使在这种情况下,这意味着指针(它指向的地址)是按值存储的。
someType* toDelete = mySomeTypeMap.take(key);
例如:

someType* toDelete1 = mySomeTypeMap.take(key);
someType* toDelete2 = mySomeTypeMap.take(key);
someType* toDelete3 = toDelete1;
toDelete1 = NULL;
toDelete2和toDelete3仍将指向原始对象

删除后不应使指针为null,而应将其从映射中删除,或将该键的值设置为null

someType* toDelete = mySomeTypeMap.take(key);
这是在堆栈上创建的指针变量,其值设置为您在映射中保留的值。您不需要将其设置为NULL,因为它立即超出范围

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

mySomeTypeMap.insert(key, 0);
这是在堆栈上创建的指针变量,其值设置为您在映射中保留的值。您不需要将其设置为NULL,因为它立即超出范围

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

mySomeTypeMap.insert(key, 0);

第一个猜测:您没有遵循
someType
的三个规则。向我们展示
someTye
的定义。另外,
mySomeTypeMap.take(key)
返回原始元素的副本或指向元素本身的指针是什么?构造函数和析构函数都是空的……这是一个非常简单的数据类,不包含任何我需要清理的指针。我没有显式地实现复制构造函数。这怎么会造成问题呢?为了回答您的第二个问题,
QMap::take(…)
从映射中删除条目,那么之后将其置零又有什么意义呢?地图上不存在,副本立即超出范围。
Blah
来自哪里
toDelete=mySomeTypeMap.take(key)
从映射中删除索引为
key
的项,并将其存储在
toDelete
中。在调用
delete
后,将其指定给
toDelete
(一个局部变量)是没有意义的。问题一定出在别处。首先猜测:对于
someType
,您没有遵循三的规则。向我们展示
someTye
的定义。另外,
mySomeTypeMap.take(key)
返回原始元素的副本或指向元素本身的指针是什么?构造函数和析构函数都是空的……这是一个非常简单的数据类,不包含任何我需要清理的指针。我没有显式地实现复制构造函数。这怎么会造成问题呢?为了回答您的第二个问题,
QMap::take(…)
从映射中删除条目,那么之后将其置零又有什么意义呢?地图上不存在,副本立即超出范围。
Blah
来自哪里
toDelete=mySomeTypeMap.take(key)
从映射中删除索引为
key
的项,并将其存储在
toDelete
中。在调用
delete
后,将其指定给
toDelete
(一个局部变量)是没有意义的。问题一定在其他地方。好的,基本类型的“默认cunstructed值”由Qt容器设置为0,所以您不需要我答案中的最后一行。问题一定在其他地方。好的,基本类型的“默认cunstructed值”由Qt容器设置为0,所以您不需要我答案中的最后一行。问题一定在别处。