STL vector里的segmentation error问题。

byres 2011-11-28 02:18:13
这个程序,11行那里,如果n=3,就有Segmentation Error,n=4, n=2 等等其他数都没有问题。
怎么回事啊?(编译器linux下 gcc 4.4.5 )


#include <iostream>
#include <vector>
using namespace std;

int main ()
{
int i, n;
vector<int> myvector;
for (i=1; i<=10; i++) myvector.push_back(i);
vector<int>::iterator iter;
n = 4;
for (iter=myvector.begin(); iter<myvector.end(); iter++)
{
if (*iter%n == 0)
myvector.push_back(999);
}
return 0;
}
...全文
326 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
youkuxiaobin 2011-11-28
  • 打赏
  • 举报
回复
vector一般是2的幂次增长,push_back如果原来分配的内存不够就会重新分配,这个时候迭代器(也就是指针)就失效了
byres 2011-11-28
  • 打赏
  • 举报
回复
多谢大家了。
pengzhixi 2011-11-28
  • 打赏
  • 举报
回复
去看看effective stl就知道了
byres 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 qscool1987 的回复:]

引用 9 楼 byres 的回复:
不过我怎么看到有的文章说erase也会使iterator失效啊?erase不会重新分配内存啊。

看来你对于vector的内存布局不熟悉,vector内部的元素是连续的,中间是没有间隔空间的,deque也是这样,数组也是这样,所以他们才能有下标进行操作,你试想一下你在中间删掉某一个元素之后会出现什么情况?为了保证数据连续性Vector在删除一个元素之后,……
[/Quote]

我的理解是:因为erase()返回的是下一个元素的地址,而后面元素位置变化后,地址是还连续的,所以iterator不会失效。 网上也有不少文章说用iterator删除元素的。

我应该抽时间看看STL源码了。
qscool1987 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 byres 的回复:]
不过我怎么看到有的文章说erase也会使iterator失效啊?erase不会重新分配内存啊。
[/Quote]
看来你对于vector的内存布局不熟悉,vector内部的元素是连续的,中间是没有间隔空间的,deque也是这样,数组也是这样,所以他们才能有下标进行操作,你试想一下你在中间删掉某一个元素之后会出现什么情况?为了保证数据连续性Vector在删除一个元素之后,那么这个元素之后的所有的元素的位置都会发生变化,而迭代器不同,当一个迭代器你初始化了之后就他就一直指向你给他分配的地址,所以当你删除一个元素之后,那么由于元素的移动导致迭代器所指向的空间里面的元素发生变化,从而失效.
pengzhixi 2011-11-28
  • 打赏
  • 举报
回复
这个很正常啊,你去看erase的实现就知道哪些元素的迭代器失效
byres 2011-11-28
  • 打赏
  • 举报
回复
不过我怎么看到有的文章说erase也会使iterator失效啊?erase不会重新分配内存啊。
byres 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 pengzhixi 的回复:]

可能会引起内存的重新分配(当原来的内存不足以存放下新添加的元素时候)那么原来的iter肯定会失效。而且即使你的迭代器不失效,那么你的iter可能永远也到不了myvector.end(); 因为随着你不停的push_back那么元素也不停的增多。可能永远无法到达myvector.end()
[/Quote]

刚看了看vector的一些文档,确实忽略了内存的重新分配。
pengzhixi 2011-11-28
  • 打赏
  • 举报
回复
可能会引起内存的重新分配(当原来的内存不足以存放下新添加的元素时候)那么原来的iter肯定会失效。而且即使你的迭代器不失效,那么你的iter可能永远也到不了myvector.end(); 因为随着你不停的push_back那么元素也不停的增多。可能永远无法到达myvector.end()
byres 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 pengzhixi 的回复:]

因为push_back会导致迭代器失效,所以每次的iter你都需要重新获得,当然最好的办法是通过下标。而不通过迭代器。
[/Quote]

多谢回答。不过还是不太理解为什么push_back会导致迭代器失效,vector的内存物理地址是连续的啊?
iamnobody 2011-11-28
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 pengzhixi 的回复:]
C/C++ code
int main ()
{
int i, n;
vector<int> myvector;
for (i=1; i<=10; i++) myvector.push_back(i);
vector<int>::iterator iter;
n = 3;
for (int i=0;i!=10;++i)
{
……
[/Quote]

三楼正解,随机访问迭代器可以用小于比较
pengzhixi 2011-11-28
  • 打赏
  • 举报
回复
int main ()
{
int i, n;
vector<int> myvector;
for (i=1; i<=10; i++) myvector.push_back(i);
vector<int>::iterator iter;
n = 3;
for (int i=0;i!=10;++i)
{
if (myvector[i]%n == 0)
myvector.push_back(999);
}

system("pause");
return 0;
}
注意不能写成i<myvector.size();否则 随着push_back其大小不断增大就会变成死循环直到内存爆了。
hastings 2011-11-28
  • 打赏
  • 举报
回复
看下来震惊了两次:
看到迭代器比较你用小于符号..
在原来的容器里push_back..
pengzhixi 2011-11-28
  • 打赏
  • 举报
回复
因为push_back会导致迭代器失效,所以每次的iter你都需要重新获得,当然最好的办法是通过下标。而不通过迭代器。

65,183

社区成员

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

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