容器元素为指针时,删除元素的问题

aatny1 2009-05-20 12:06:35
A* a = new A;
A* b = new B;
vector<A* > v;
v.push_back(a);
v.push_back(b);
for(vector<A*>::iterator it = v.begin();it != v.end();++it)
{
if(*it == b)
{
delete *it;
v.erase(it);
}
}
这样删除一个指针元素可行吗?
...全文
351 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
s79947171 2010-04-07
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 hejinjing_tom_com 的回复:]
引用楼主 aatny1 的帖子:
A* a = new A;
A* b = new B;
vector <A* > v;
v.push_back(a);
v.push_back(b);
for(vector <A*>::iterator it = v.begin();it != v.end();++it)
{
if(*it == b)
{
delete *it;
v.eras……
[/Quote]
这个代码我在VS 2005还是不能通过,首先不说编译的问题,你这个逻辑就是有错误的
v.erase(it)被执行以后,获得的是你下一个iterator,与it++一个道理,然后再for循环中又++it相当于被加了2才次
如果vector中存在这样的数据[数据是我模拟的]12,12,123,456而12是你要删除的数据,你只能删除第一个12
cumtwmy 2009-11-23
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 hejinjing_tom_com 的回复:]
这样删除一个指针元素可行吗?

不够严谨! 正确的做法如下并加有注释
C/C++ code
for(vector::iterator it = v.begin();it != v.end();++it)
{
if(*it == b)
{
delete *it;
v.erase(it); // 当你删除最后一个元素时,it 已等于尾指针
if(it==v.end())
break; // 此时要终止循环,否则 ++it 后,it!=v.end() 永远成立
} // 指针成为野指针,访问指针所指内容时出现运行期错误。
}
[/Quote]

测试一下,确实是这样的!
但是set不能这样用。仍然出现野指针错误,实验过了。
Sou2012 2009-05-20
  • 打赏
  • 举报
回复
UP。。。。
MichaelBomb 2009-05-20
  • 打赏
  • 举报
回复
正在学习容器,学习了
hjjdebug 2009-05-20
  • 打赏
  • 举报
回复
[Quote=引用楼主 aatny1 的帖子:]
A* a = new A;
A* b = new B;
vector <A* > v;
v.push_back(a);
v.push_back(b);
for(vector <A*>::iterator it = v.begin();it != v.end();++it)
{
if(*it == b)
{
delete *it;
v.erase(it);
}
}
这样删除一个指针元素可行吗?
[/Quote]
不够严谨! 正确的做法如下并加有注释

for(vector <A*>::iterator it = v.begin();it != v.end();++it)
{
if(*it == b)
{
delete *it;
v.erase(it); // 当你删除最后一个元素时,it 已等于尾指针
if(it==v.end())
break; // 此时要终止循环,否则 ++it 后,it!=v.end() 永远成立
} // 指针成为野指针,访问指针所指内容时出现运行期错误。
}

aatny1 2009-05-20
  • 打赏
  • 举报
回复
谁能说说前一种方法出现异常是为什么吗?如果按你们的说法,是不会出现异常的。
aatny1 2009-05-20
  • 打赏
  • 举报
回复
这段代码在dev-cpp上测试,出现了内存访问违例,i.e. 这段代码有问题!
测试了另一种方法,正常:
vector<A*>::iterator it = v.begin();
for(vector<A*>::size_type i = 0;i < v.size();i++)
{
if(v[i] == b)
{
delete v[i];
v.erase(it);
}
++it;
}
lsldd 2009-05-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 aatny1 的回复:]
问题是delete *it后,*it已不存在,再v.erase(it),it所指的内容都没了,erase(it)会正常吗?这里面好像有问题。
[/Quote]
没关系。因为你保存的是指针。delete并没有修改指针本身,他仅仅是释放了指针指向的那块资源。
HelloDan 2009-05-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 aatny1 的回复:]
问题是delete *it后,*it已不存在,再v.erase(it),it所指的内容都没了,erase(it)会正常吗?这里面好像有问题。
[/Quote]

是指针指向的内容没有的,但是指针还在的,内容是指针,可以的。没有问题。
qizhao2001 2009-05-20
  • 打赏
  • 举报
回复
1. 肯定你的做法,可以
2. 推荐做法 自己做一层薄的封装 或者直接用 boost的 share_ptr<>,
注意,auto_ptr是不能用于容器的
aatny1 2009-05-20
  • 打赏
  • 举报
回复
问题是delete *it后,*it已不存在,再v.erase(it),it所指的内容都没了,erase(it)会正常吗?这里面好像有问题。
Wolf0403 2009-05-20
  • 打赏
  • 举报
回复
同意一楼二楼意见。
agui1226 2009-05-20
  • 打赏
  • 举报
回复
可以
next163 2009-05-20
  • 打赏
  • 举报
回复
顺次找到b之后,删除之,然后再次循环(因为it没有到达 end,再次运行到
if(*it == b)
的时候会出问题的,因为it++在else里,但上次删除被执行,但++没有执行,再次*it的时候存在违规了。

[Quote=引用 21 楼 biosli 的回复:]
引用 13 楼 s79947171 的回复:
C/C++ code
A* a = new A;
A* b = new A;
vector <A* > v;
v.push_back(a);
v.push_back(b);
for(vector <A*>::iterator it = v.begin();it != v.end();)
{
if(*it == b)
{
delete *it;
it=v.erase(it);
} else
++it;
}
[/Quote]
amuzing 2009-05-20
  • 打赏
  • 举报
回复
可以
scsnsjsl_cs_dn 2009-05-20
  • 打赏
  • 举报
回复
biosli 2009-05-20
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 s79947171 的回复:]
C/C++ code
A* a = new A;
A* b = new A;
vector <A* > v;
v.push_back(a);
v.push_back(b);
for(vector <A*>::iterator it = v.begin();it != v.end();)
{
if(*it == b)
{
delete *it;
it=v.erase(it);
} else
++it;
}



如楼上的我运行错误,感觉v.erase(it)后在++可是删除的时候迭代器不是失效了吗?还可以++吗?感觉删除的时候应该重新定义迭代器的位置才对!
[/Quote]

此答案正解,erase之后获得的是你下一个iterator,这个操作是必要的,不然会出现内存失效。
yshuise 2009-05-20
  • 打赏
  • 举报
回复
好的方法应该只是释放内存,而不是改变容器的大小。这样效率低又容易出错。
adventurelw 2009-05-20
  • 打赏
  • 举报
回复
作为一个谨慎的策略,建议楼主用下标吧。
beyond071 2009-05-20
  • 打赏
  • 举报
回复
学习了
加载更多回复(8)

65,211

社区成员

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

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