有一张地图,它将int
映射到Test*
。
之前分配所有Test*
指针并稍后将其分配给地图。然后,我delete
输入地图的值并将其设置为null
。
之后,它检查one
的有效性,它应该是null
。 但,one
不是null
。
#include <QString>
#include <QMap>
#include <QDebug>
class Test {
QString name;
public:
Test(const QString &name) : name(name) {}
QString getName() const { return name; }
};
int main() {
QMap<int, Test*> map;
Test *one = new Test("one");
Test *two = new Test("two");
Test *three = new Test("three");
map.insert(1, one);
map.insert(2, two);
map.insert(3, three);
for (auto itr = map.begin(); itr != map.end(); itr++) {
Test *x = *itr;
if (x) {
delete x;
x = 0; // ** Sets null to the pointer ** //
}
}
if (one) // ** Here one is not 0 ?! ** //
qDebug() << one->getName() << endl; // ** And then here crashes ** //
}
我想,当我在循环中delete
时,我错过了一些东西。
如何修复?
第二个问题是,它是否正确delete
s 分配的指针?
答案 0 :(得分:4)
在循环中,变量x
是仅在循环内部的本地指针。当您将其设置为NULL
时,实际上并未将任何其他指针设置为NULL
。
您应该将通过解除引用迭代器返回的引用设置为NULL
:
*itr = nullptr;
这将使地图中的指针为NULL
,但其他指针仍将指向现已释放的内存区域。
当你有两个指针时,它看起来像这样:
+-----+ | one | ---\ +-----+ | +---------------+ >--> | Test instance | +-----+ | +---------------+ | x | ---/ +-----+
如果设置一个指针,它看起来像这样:
+-----+ | one | ---\ +-----+ | +---------------+ >--> | Test instance | +-----+ +---------------+ | x | +-----+
变量x
为NULL
,但变量one
仍然指向对象。如果该对象已被删除,则取消引用该指针将导致未定义的行为。
答案 1 :(得分:2)
删除所有内容的最简单方法是:
qDeleteAll(map);