【发布时间】:2014-02-18 14:41:57
【问题描述】:
我有一个充满动态创建的对象的 Qlist。在终止我的程序之前,我调用了 myqlist.clear()
我的问题是:这是否也会删除(释放)列表中包含的对象? Valgrind 给了我一些丢失的块,我想知道我是否误解了 qlist clear 方法的工作原理。
或者,我是否需要遍历 qlist 并删除每个对象?
更新:我可以确认 mylist.erase(iterator) 正在从列表中删除项目,但没有释放动态分配的对象。 (对象是一个动态实例化的类)。很奇怪!我从 Qlist 切换到 QLinkedList 但结果相同。请记住,我的 QLinkedList 是 QLinkedList
这是实际代码,以防有人发现我做错了什么:
// Here I define a couple important items. Note that AMISendMessageFormat is a class
typedef QLinkedList<AMISendMessageFormat> TSentMessageQueue;
TSentMessageQueue m_sentMessageQueue;
// Here I create the message and append to my QLinkedList
AMISendMessageFormat *newMessage = new AMISendMessageFormat(messageToSend);
m_sentMessageQueue.append(*newMessage);
// Here I delete
for (TSentMessageQueue::Iterator sMessagePtr = m_sentMessageQueue.begin(); sMessagePtr != m_sentMessageQueue.end(); )
{
sMessagePtr = m_sentMessageQueue.erase(sMessagePtr);
qDebug() << "Sent size after erase: " << m_sentMessageQueue.size(); // Confirmed linked list is shrinking in size
}
在遍历列表并擦除之后,valgrind 显示每个 AMISendMessageFormat 对象都是丢失的块!
我怀疑这与使用迭代器在循环内擦除有关...但我无法理解这一点!
请参阅下面的详细解决方案...问题是 append 函数创建一个副本并将其添加到列表中...我虽然它正在添加实际对象(不是副本)...所以问题是'新的副本被泄露了。
【问题讨论】:
-
一个更好的习惯用法可能是在你的
QList中存储智能指针而不是原始指针,这样你就不必明确地处理它。它还使谁拥有这些对象的所有权更加明确。 -
@ereOn 总的来说这是个好建议,但并不真正适用于 Qt。
-
@pmr: 在docs 中没有任何地方声明
QList拥有指针的所有权,我相信Qt 有一个QSharedPointer,所以我不确定这如何不适用。我在这里错过了什么吗? -
@ereOn 是的,但是如果 OP 正在使用 QObjects,这很有可能(因为这是一个 Qt 问题)。我只是觉得跳过这个话题的答案并不完整。
-
@Michelle:你在附加一个对象,而不是一个指向对象的指针,所以
append没有办法接受它。它不知道涉及指针。在append看到它之前取消引用指针。您还必须学会不要无缘无故地在堆上分配东西。如果它适合堆栈,请使用堆栈。
标签: c++ qt memory delete-operator qlist