注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Nihui's Blog

nihui的私人空间和日志

 
 
 

日志

 
 

QList 使用迭代器在循环中删除元素的陷阱  

2011-12-18 10:22:28|  分类: 工作側記 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

陷阱就在下面这段中哦。我一直以为是正确的写法呢,直到昨天下午做 zzzz 的时候,delete 那句话总是引起段错误才迫使我去 google 上找了很久。我先不说陷阱在哪儿,你可以先琢磨琢磨~~
QList<MyObj*> objects;

QList<MyObj*>::Iterator it = objects.begin();
QList<MyObj*>::Iterator end = objects.end();
while ( it != end ) {
MyObj* obj = *it;
if ( obj->id == id ) {
it = objects.erase( it );
delete obj;
}
else {
++it;
}
}

QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog


好了,看了那么多泡泡之后我来公布修正后的代码了
QList<MyObj*> objects;

QList<MyObj*>::Iterator it = objects.begin();
QList<MyObj*>::Iterator end = objects.end();
while ( it != end ) {
MyObj* obj = *it;
if ( obj->id == id ) {
it = objects.erase( it );
end = objects.end();
delete obj;
}
else {
++it;
}
}
看到那行新加的粗体字了没有?QList erase 之后会导致整个数据结构造成一次重排,end 这个迭代器会无效,如果 end 没有相应改变的话,循环到最后的一轮会访问到无效的迭代器,所以就段错误了。这点上行为和 std::list 不同。在深入些的话,就是 QList 内部的数据结构其实不是链表,而是个“很高效的 vector”,每次对内容删除或增加都会造成所有元素的重新布局,而 QLinkedList 的行为则不会哦。

QList::erase 的文档没有写这注意要点,被坑了呀~~

最后更新一张 zzzz 的截图,放弃了 khtml/webkit 的方案,改用了轻量级的 qtextbrowser 渲染 html,显示速度相当快哦。
QList 使用迭代器在循环中删除元素的陷阱 - nihui - Nihuis Blog
  评论这张
 
阅读(2623)| 评论(12)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017