为什么会出现这个异常?

cppTrier 2003-06-15 02:52:02
#include <iostream>
#include <vector>
using namespace std;
int main()
{

vector<int> r;
r.push_back(2);
for (int i = 3; i<=10; i++)
for (vector<int>::iterator it = r.begin(); it < r.end(); it++)
if ((i% *it) == 0) r.push_back(i);// 运行时这句为什么会出出一个integer divided by zero exception?
}
将 r.push_back(i) 换成其它的语句就没有问题,调试环境是VS.net VS.net 2003,是VC.net的标准库的问题?
...全文
26 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
myname_xie 2003-06-16
  • 打赏
  • 举报
回复
我解释为什么*it会是0,
首先,r.end()元素是用元素的缺省构造函数构造的一个函数,因为是整型,所以被初始化为0,
接着,你调用r.push_back(i)前,it是指向第一个元素,那么调push_back用后整个数组序列被重新排列,但是it中的位置并为被重新排列,那么你执行it++后,it指向的是第一次使用push_back(2)的那个序列的end(),所以此时*it为0,因为push_back(i)的end()和it没有联系,所以it < end();此句话会产生不可知结果
但为什么使用reserve就不会出现这种情况,因为用reserve时系统为r分配连续的存储空间,所以不会出现你所说的异常,(另外需要注意的是,不管是否出现异常,你对vector进行添加和删除,必须从新刷新所有的引用、指针和叠代器,否则出现不可知结果,这是stl库的描述)
cppTrier 2003-06-16
  • 打赏
  • 举报
回复
谢谢大家的帮忙, 我大概知道原因了。这段语句是在教同学C++的时候他写的,所以确实是一个死循环,但是不知道的是为什么会有divided by zero exception。

估计是死循环的时候不断向vector添加数据导致vector大搬家,而使iterator失效导致的。
看样子下次应该少用vector的iterator了 好大一个陷阱啊。

另:今天在写另一个程序的时候发现vc.net的vector如果不事先reserve窨,很容易就会搬家,尤其是一开始生成一个空vector然后再向其中添加元素的时候。有谁知道vc.net的vector默认reserve的大小是多少吗?
birth_chen 2003-06-15
  • 打赏
  • 举报
回复
那不是因为list的问题,而是程序本身的逻辑有问题,在4加进list之后,end()变了,循环还没终止,所以继续it++,进入新的一次循环,此时i==4而*it==4故if判断满足,继续push_back(),而使得end()又变了,所以一直死循环,不断的push_back(4)
晨星 2003-06-15
  • 打赏
  • 举报
回复
list也不行,已经试过了,死循环。
birth_chen 2003-06-15
  • 打赏
  • 举报
回复
对于vector来说push_back()会修改迭代器,可能(并不是一定)导致it不再指向原来的位置。至于begin()和end()虽然也改变了,但在程序中并不会导致什么问题,主要是it。
标准容器里面,好像只有list的插入操作不会改变原来的iterator的指向(deque不知道是不是?请高手指教)。
yecao_kinux 2003-06-15
  • 打赏
  • 举报
回复

//调试程序 src : VC6 /Win2000 server
#include <iostream>
#include <vector>

using namespace std;

int main()
{
vector<int> r;
r.push_back(2);

for(int i = 3; i<11; i++)
{
for (vector<int>::iterator it = r.begin(); it<r.end(); ++it)//it++)
{
if ((i%(*it)) == 0)
{
r.push_back(i);// 运行时这句为什么会出出一个integer divided by zero exception?
}
std::cout<<"i = "<<i<<" (*it) = "<<(*it)<<std::endl;
}
}

return 0;
}
yecao_kinux 2003-06-15
  • 打赏
  • 举报
回复
就这句来看integer divided by zero exception是因为除数为0的情况,在VC调试下也的确有0的情况,只是不知如何会出现这种情况,到目前为止?????

运行情况:
//std::cout<<"i = "<<i<<" (*it) = "<<(*it)<<std::endl;//打印结果如下

i = 3 (*it) = 2
i = 4 (*it) = -572662307
i = 5 (*it) = 2
i = 5 (*it) = 4
i = 6 (*it) = -572662307
i = 7 (*it) = 2
i = 7 (*it) = 4
i = 7 (*it) = 6
i = 8 (*it) = 2
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = 65
i = 8 (*it) = 64
i = 8 (*it) = 3410180
i = 8 (*it) = 3410180
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = -572662307
i = 8 (*it) = 160
i = 8 (*it) = 81
i = 8 (*it) = 4726672
i = 8 (*it) = 4726624 //下一步出错

//why ???


yecao_kinux 2003-06-15
  • 打赏
  • 举报
回复
刚才在VC下调试了一下,同意steedhorse(晨星)的看法,还没有好办法.关注中....
lzh7800 2003-06-15
  • 打赏
  • 举报
回复
单步跟踪,当i=4时,i=4并没有被压进容器,下列程序段进入死循环
for (vector<int>::iterator it = r.begin(); it < r.end(); it++)
if ((i% *it) == 0) r.push_back(i);
}
晨星 2003-06-15
  • 打赏
  • 举报
回复
每次push_back执行后,r.begin(),r.end()都会发生变化,也就是vector在内存中的位置被移到其他地方去了。所以你再原来的跌代器上++,那后再取值,就会发生问题。
vector的内部实现对用户是透明的,它本来就不是简单的数组,跌代器也不是简单的下标,所以我觉得很难实现一边修改,一边遍历。

继续关注。。。
alenwelkin 2003-06-15
  • 打赏
  • 举报
回复
你换成什么语句就没有问题了??

24,855

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 工具平台和程序库
社区管理员
  • 工具平台和程序库社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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