std::vector调用erase函数的问题

clever101
博客专家认证
2019-03-06 09:50:11
今天用 VS2012 (vc11)调试的时候发现了一个惊人的大问题,就是 vector 对象中的元素如果是用户类型(即 class),对容器调用 erase 是非常危险的!因为按照 vc11 的源码,erase 的时候是把后面元素的内容整体向前移动(纯一大段内存拷贝,而不是对象逐个析构和拷贝构造),再销毁尾部的元素。也就意味着,被删除的元素根本就没有机会执行析构函数,内容就被覆写了。如果对象内部有指针(二级),直接被覆盖可能导致严重后果(例如内存泄漏,或者 vector 析构时运行时崩溃)。这种危险只针对容器元素是用户类型的情况,对于内置基本数据类型(char,int,等),包括指针类型,则调用 erase 是不会有上述危险的。

那么保存用户自定义对象(含有指针成员)的vector的erase该怎么实现呢?
...全文
327 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
clever101 2019-11-14
  • 打赏
  • 举报
回复
使用erase需要实现赋值运算符=
clever101 2019-03-06
  • 打赏
  • 举报
回复
引用 6 楼 yshuise 的回复:
直接遍历,
delete itor;
这肯定不行嘛。你存储的不一定是new出来的,可以直接delete吗?靠谱点的办法应该是直接调用对象的析构函数。
yshuise 2019-03-06
  • 打赏
  • 举报
回复
直接遍历,
delete itor;
倚栏|听风 2019-03-06
  • 打赏
  • 举报
回复
自定义类型我一般都是用指针的,还真没了解过这种问题... 涨知识..
  • 打赏
  • 举报
回复
引用 2 楼 宁可十年不将军,不可一日不拱卒 的回复:
你看看,就是把对象内存的内容拷贝和覆盖了,之前的被 erase 的哪个对象,根本就不执行析构函数。
明白你的意思了,被删除的那个对象,没有调用析构函数是有问题。 确实如此啊。
  • 打赏
  • 举报
回复
引用 2 楼 宁可十年不将军,不可一日不拱卒 的回复:
你看看,就是把对象内存的内容拷贝和覆盖了,之前的被 erase 的哪个对象,根本就不执行析构函数。
是的,执行析构函数倒是会有问题的。 比如对象中有一个指针,动态分配的内存,析构时,释放了内存。 那么拷贝对象的指针再访问释放过的内存就有问题了。
clever101 2019-03-06
  • 打赏
  • 举报
回复
引用 1 楼 zjq9931 的回复:
有指针也不会有问题啊。 指针(地址)已经拷贝了,指针指向的动态分配的内存地址是没有变化的。vector的移动也不会改变这些地址里面的内容。
你看看,就是把对象内存的内容拷贝和覆盖了,之前的被 erase 的哪个对象,根本就不执行析构函数。
  • 打赏
  • 举报
回复
有指针也不会有问题啊。 指针(地址)已经拷贝了,指针指向的动态分配的内存地址是没有变化的。vector的移动也不会改变这些地址里面的内容。
真相重于对错 2019-03-06
  • 打赏
  • 举报
回复
个人以为,erase 意思就是把对象从容器中移除,并不一定要把对象析构 可以这样 (*iter).~obj();
sdghchj 2019-03-06
  • 打赏
  • 举报
回复
scalar type : http://c.biancheng.net/ref/34.html
sdghchj 2019-03-06
  • 打赏
  • 举报
回复
好像发现新大陆对吧。 你的图里的erase里调用的明显是三参数的_Move函数,你直接看那个四参数的重载版本的_Move函数来得出结论是不是有点片面噢? 而且那个四参数的重载版本的_Move函数的最后一个参数类型名带有Scalar单词,你知道scalar是什么意思吗?
clever101 2019-03-06
  • 打赏
  • 举报
回复
引用 8 楼 taodm 的回复:
倒!你知道使用容器的最基本要求就是实现正确的拷贝构造函数、赋值运算符、析构函数。 另外,你知道move有多少重载版本么。你看到的是真正调用的么。 还是买本《effective stl》补足课吧。
大侠,实现正确的拷贝构造函数、赋值运算符、析构函数也会存在我说的问题吧。《effective stl》我会看的。
taodm 2019-03-06
  • 打赏
  • 举报
回复
倒!你知道使用容器的最基本要求就是实现正确的拷贝构造函数、赋值运算符、析构函数。 另外,你知道move有多少重载版本么。你看到的是真正调用的么。 还是买本《effective stl》补足课吧。

64,651

社区成员

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

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