C++ 使QMap内的指针值无效
我有一个似乎很奇怪的问题,但这可能是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
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,所以您不需要我答案中的最后一行。问题一定在别处。