std::list 存储对象指针,delete的问题

奶糖人五号 2010-04-12 02:17:34

list<CObj*>::iterator ip;
list<CObj*>::iterator it;
for (ip = m_list.begin();ip != m_list.end();)
{
it = ip;
it++;

delete *ip;
m_list.erase(ip);

ip = it;
}


每次释放到第二个节点时,就会出错。 请问这段代码问题在哪里?
...全文
2223 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
奶糖人五号 2010-04-15
  • 打赏
  • 举报
回复
问题解决。和链表无关,COM对象的问题,呵呵
LittleJohny 2010-04-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 classpatterns 的回复:]

m_list.erase(ip);
delete *ip;
[/Quote]

这样一运行,就出错了,erase调用后,ip不再指向list里的元素了,*ip解引用失败。。。
z0203153008 2010-04-12
  • 打赏
  • 举报
回复
2L
FingerStyle 2010-04-12
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 hacker1125 的回复:]

delete *ip;//屏蔽这句看看,m_list.erase(ip)应该就可以了
[/Quote]

你这样就内存泄漏了。


注意list里放的是指针。

楼主的list不存在跌带器失效问题。

刚 Dev C++ 测试没问题。
hacker1125 2010-04-12
  • 打赏
  • 举报
回复
delete *ip;//屏蔽这句看看,m_list.erase(ip)应该就可以了
rtygbwwwerr 2010-04-12
  • 打赏
  • 举报
回复
m_list.erase(ip);执行后,m_list的迭代器it,需要从新设置。
m_list.erase(ip) => it = m_list.erase(ip)
FingerStyle 2010-04-12
  • 打赏
  • 举报
回复
erase不是ip指向的内存 而是erase掉 list内的指针。
老邓 2010-04-12
  • 打赏
  • 举报
回复
这是一个正确的例子,供参考:
#include <iostream>
#include <list>
using namespace std;

void print(list<int>);

int main()
{
list<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);
//删除array数组中所有6
list<int>::iterator itor;
list<int>::iterator itor2;

for (itor = array.begin(); itor != array.end();)
{
if (6 == *itor)
itor=array.erase(itor);
else
itor++;
}
print(array);
system("pause");
return 0;
}
void print(list<int> v)
{
cout << "\n vector size is:" << v.size() << endl;
list< int >::iterator p = v.begin();
while ( p != v.end() )
cout << *p++ << endl;
}
cy330206 2010-04-12
  • 打赏
  • 举报
回复
delete *ip;
m_list.erase(ip);
你已经释放了,在erase干嘛,
老邓 2010-04-12
  • 打赏
  • 举报
回复
最近看了看STL的Container,对迭代器(iterator)的失效问题一直都很困惑。做了一些实验,有了一定的了解,总结如下,以便备忘。

迭代器(iterator)是一个可以对其执行类似指针的操作(如:解除引用(operator*())和递增(operator++()))的对象,我们可以将它理解成为一个指针。但它又不是我们所谓普通的指针,我们可以称之为广义指针,你可以通过sizeof(vector::iterator)来查看,所占内存并不是4个字节。

首先对于vector而言,添加和删除操作可能使容器的部分或者全部迭代器失效。那为什么迭代器会失效呢?vector元素在内存中是顺序存储,试想:如果当前容器中已经存在了10个元素,现在又要添加一个元素到容器中,但是内存中紧跟在这10个元素后面没有一个空闲空间,而vector的元素必须顺序存储一边索引访问,所以我们不能在内存中随便找个地方存储这个元素。于是vector必须重新分配存储空间,用来存放原来的元素以及新添加的元素:存放在旧存储空间的元素被复制到新的存储空间里,接着插入新的元素,最后撤销旧的存储空间。这种情况发生,一定会导致vector容器的所有迭代器都失效。

我们看到实现上述所说的分配和撤销内存空间的方式以实现vector的自增长性,效率是极其低下的。为了使vector容器实现快速的内存分配,实际分配的容器会比当前所需的空间多一些,vector容器预留了这些额外的存储区,用来存放新添加的元素,而不需要每次都重新分配新的存储空间。你可以从 vector里实现capacity和reserve成员可以看出这种机制。

capacity和size的区别:size是容器当前拥有的元素个数,而capacity则指容器在必须分配新存储空间之前可以存储的元素总数。

vector迭代器的几种失效的情况:
1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。
2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时first和end操作返回的迭代器都会失效。
3.当进行删除操作(erase,pop_back)后,指向删除点的迭代器全部失效;指向删除点后面的元素的迭代器也将全部失效。

deque迭代器的失效情况:
在C++Primer一书中是这样限定的:
1.在deque容器首部或者尾部插入元素不会使得任何迭代器失效。
2.在其首部或尾部删除元素则只会使指向被删除元素的迭代器失效。
3.在deque容器的任何其他位置的插入和删除操作将使指向该容器元素的所有迭代器失效。
但是:我在vs2005测试发现第一条都不满足,不知为何?等以后深入STL以后慢慢的领会吧!

只有list的迭代器好像很少情况下会失效。也许就只是在删除的时候,指向被删除节点的迭代器会失效吧,其他的还没有发现。
老邓 2010-04-12
  • 打赏
  • 举报
回复
ip = m_list.erase(ip);
此时要去掉ip++
迭代器失效了
FingerStyle 2010-04-12
  • 打赏
  • 举报
回复
m_list.erase(ip);
delete *ip;

64,318

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧