C++ 带有QListWidget addItem()和#x2B的Memoryleak;setItemWidget()
当我按下一个键时,将会有一个对引擎的查询。通过添加一个项目并设置小部件,将结果放入C++ 带有QListWidget addItem()和#x2B的Memoryleak;setItemWidget(),c++,qt,memory-leaks,qt5,C++,Qt,Memory Leaks,Qt5,当我按下一个键时,将会有一个对引擎的查询。通过添加一个项目并设置小部件,将结果放入QListWidget。不知何故,这导致了大量内存溢出,甚至使我的机器崩溃。但是我不明白这个错误。clear()是否不删除传递给QListWidget的项目以及setItemWidget()设置的小部件。我甚至试着自己删除它们(评论),但仍然得到了一个memoryleak。我猜错误在if(!results.empty())-块中,因为注释掉它会插入memoryleak void Widget::onTextEdit
QListWidget
。不知何故,这导致了大量内存溢出,甚至使我的机器崩溃。但是我不明白这个错误。clear()
是否不删除传递给QListWidget
的项目以及setItemWidget()
设置的小部件。我甚至试着自己删除它们(评论),但仍然得到了一个memoryleak。我猜错误在if(!results.empty())
-块中,因为注释掉它会插入memoryleak
void Widget::onTextEdited(const QString & text)
{
// QListWidgetItem * takenItem;
// while (takenItem = _results->takeItem(0)){
// delete _results->itemWidget(takenItem);
// delete takenItem;
// }
_results->clear(); _results->hide();
if (!text.isEmpty())
{
const std::vector<const Items::AbstractItem *> results = _engine.request(text);
if (!results.empty())
{
for (auto i : results){
QListWidgetItem *lwi = new QListWidgetItem;
_results->addItem(lwi);
ListItemWidget *w = new ListItemWidget;
w->setName(i->name());
w->setTooltip(i->path());
_results->setItemWidget(lwi, w);
}
_results->setFixedHeight(std::min(5,_results->count()) * 48); // TODO
_results->show();
}
}
this->adjustSize();
}
void小部件::onTextEdited(const QString&text)
{
//QListWidgetItem*takenItem;
//而(takenItem=\u结果->takeItem(0)){
//删除_results->itemWidget(takenItem);
//删除takenItem;
// }
_结果->清除();_结果->隐藏();
如果(!text.isEmpty())
{
const std::vector results=_engine.request(文本);
如果(!results.empty())
{
用于(自动i:结果){
QListWidgetItem*lwi=新的QListWidgetItem;
_结果->附加项(lwi);
ListItemWidget*w=新的ListItemWidget;
w->setName(i->name());
w->setTooltip(i->path());
_结果->setItemWidget(lwi,w);
}
_结果->设置固定高度(标准::分钟(5,_结果->计数())*48);//待办事项
_结果->显示();
}
}
此->调整大小();
}
您绝对应该使用内存泄漏检测工具,而不是四处猜测:)
更新:clear()只删除项目,但不删除属于它的小部件。如果QListWidget被删除,则小部件将被删除
clear()会删除属于它的项目和小部件。您提到如果(!results.empty())注释掉可以解决问题。我认为setItemWidget部分没有任何问题。因此,我认为问题出在其他地方,可能是ListItemWidget
。试试用QLabel
替换ListItemWidget
,看看会发生什么。例如:
QListWidgetItem *lwi = new QListWidgetItem;
_results->addItem(lwi);
//ListItemWidget *w = new ListItemWidget;
//w->setName(i->name());
//w->setTooltip(i->path());
QLabel *w = new QLabel;
w->setText("Hello");
_results->setItemWidget(lwi, w);
我刚试过。记忆障碍依然存在。Valgrind告诉我没有错误。@ManuelSchneid3r,对QLabel和setItemWidget部分进行注释怎么样,只留下前两行(新的QListWidgetItem和addItem)。什么东西告诉你内存泄漏了?程序崩溃了?发现了:clear()不会删除小部件。它只是删除小部件。谢谢你的帮助,@ManuelSchneid3r,我的错!我认为clear()确实会删除widgets,因为在调用setItemWidget()之后w有一个父对象。显然,listWidget只会在其自身被删除后删除Widget。因此,在您的情况下,小部件将一直占用内存,直到listWidget被删除。