运行时vector越界!小数据不报错,换大数据报错!

yilin57 2010-08-16 09:55:36
RT
有人遇到过这种问题么,感觉很奇怪,分析逻辑也没发现错误~不知道该如何着手去寻找错误了,代码如下:
void compute_DelaunayTriangulation::get_voronoi_cell(DelaunayTriangulation &DT, CSG_Shapes *input_boundarys)
{
TSG_Point meet_point1,meet_point2;

for (int i=0; i<DT.m_vertices.size(); ++i)
{
std::vector<m_voronoi>::iterator pos;
DelaunayVertex &DV = DT.m_vertices[i];
m_voronoi start,end;
std::vector<m_voronoi> temp;

start = *DV.m_voronoi_cell.begin();
end = DV.m_voronoi_cell[DV.m_voronoi_cell.size()-1];
for (int icell = 0; icell < DV.m_voronoi_cell.size()-1; ++icell)
{
//std::vector<m_voronoi>::const_iterator element = DV.m_voronoi_cell.begin();

int count = 0;
bool mark1=false,mark2=false;
m_voronoi cell_vertex = DV.m_voronoi_cell.at(icell);
m_voronoi cell_vertex_next = DV.m_voronoi_cell.at(icell+1);

mark1 = check_out_boundary(cell_vertex.vertex);
mark2 = check_out_boundary(cell_vertex_next.vertex);
if(mark1 != mark2)
{
if(m_meet(cell_vertex.vertex,cell_vertex_next.vertex,meet_point1)==true)
{
if(mark1==true)
{
DV.m_voronoi_cell.erase(remove(DV.m_voronoi_cell.begin(), DV.m_voronoi_cell.end(), cell_vertex)
,DV.m_voronoi_cell.end());
}
else
{
DV.m_voronoi_cell.erase(remove(DV.m_voronoi_cell.begin(), DV.m_voronoi_cell.end(), cell_vertex_next)
,DV.m_voronoi_cell.end());
}

if (cell_vertex.is_valid == true)
{//拐点增添
double x_min = std::min((double)cell_vertex.vertex.e1(),meet_point1.x);
double x_max = std::max((double)cell_vertex.vertex.e1(),meet_point1.x);
double y_min = std::min((double)cell_vertex.vertex.e2(),meet_point1.y);
double y_max = std::max((double)cell_vertex.vertex.e2(),meet_point1.y);

for (int k = 0; k < boundary.size(); k++)
{
if (boundary[k].e1()>=x_min&&boundary[k].e1()<=x_max
&&boundary[k].e2()>=y_min&&boundary[k].e2()<=y_max)
{
DV.m_voronoi_cell.push_back(boundary[k]);
DV.m_voronoi_cell[DV.m_voronoi_cell.size()-1].is_valid = true;
}
}
}
DV.m_voronoi_cell.push_back(m_voronoi(c2gaPoint(meet_point1.x, meet_point1.y),default_attribute));
DV.m_voronoi_cell[DV.m_voronoi_cell.size()-1].is_valid = true;

count ++;
}
}
if (count == 2)
{
break;
}
}//for

bool mark3 = false,mark4 = false;
mark3 = check_out_boundary(end.vertex);
mark4 = check_out_boundary(start.vertex);
if (mark3 != mark4)
{
if(m_meet(end.vertex,start.vertex,meet_point2))
{
if (mark3 == true)
{
DV.m_voronoi_cell.erase(remove(DV.m_voronoi_cell.begin(), DV.m_voronoi_cell.end(), end)
,DV.m_voronoi_cell.end());
}
else
{
DV.m_voronoi_cell.erase(remove(DV.m_voronoi_cell.begin(), DV.m_voronoi_cell.end(), start)
,DV.m_voronoi_cell.end());
}
DV.m_voronoi_cell.push_back(m_voronoi(c2gaPoint(meet_point2.x, meet_point2.y),default_attribute));
DV.m_voronoi_cell[DV.m_voronoi_cell.size()-1].is_valid = true;
}
}
{//拐点增添
double x_min1 = std::min((double)end.vertex.e1(),meet_point1.x);
double x_max1 = std::max((double)end.vertex.e1(),meet_point1.x);
double y_min1 = std::min((double)end.vertex.e2(),meet_point1.y);
double y_max1 = std::max((double)end.vertex.e2(),meet_point1.y);

for (int k = 0; k < boundary.size(); k++)
{
if (boundary[k].e1()>=x_min1&&boundary[k].e1()<=x_max1
&&boundary[k].e2()>=y_min1&&boundary[k].e2()<=y_max1)
{
DV.m_voronoi_cell.push_back(boundary[k]);
DV.m_voronoi_cell[DV.m_voronoi_cell.size()-1].is_valid = true;
}
}

double x_min2 = std::min((double)end.vertex.e1(),meet_point2.x);
double x_max2 = std::max((double)end.vertex.e1(),meet_point2.x);
double y_min2 = std::min((double)end.vertex.e2(),meet_point2.y);
double y_max2 = std::max((double)end.vertex.e2(),meet_point2.y);

for (int k = 0; k < boundary.size(); k++)
{
if (boundary[k].e1()>=x_min2&&boundary[k].e1()<=x_max2
&&boundary[k].e2()>=y_min2&&boundary[k].e2()<=y_max2)
{
DV.m_voronoi_cell.push_back(boundary[k]);
DV.m_voronoi_cell[DV.m_voronoi_cell.size()-1].is_valid = true;
}
}
}
//去重复
std::sort(DV.m_voronoi_cell.begin(), DV.m_voronoi_cell.end(), sort_vector_op(DV.m_pt));
pos = std::unique(DV.m_voronoi_cell.begin(), DV.m_voronoi_cell.end());
if (pos != DV.m_voronoi_cell.end())
{
DV.m_voronoi_cell.erase(pos, DV.m_voronoi_cell.end());
}
}//for
}
...全文
400 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
huayiluo 2010-08-19
  • 打赏
  • 举报
回复
嗯。学习。
MasQua 2010-08-19
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 yilin57 的回复:]
可能之前没有说清楚
vector<SomeType> vect;
vector<DTrigulation> DT;//DTrigulation,自定义类,vect是其中一个成员
...
for(int i = 0; i < DT.size(); ++i)
{
DTrigulation test = DT[i];
SomeType start = test.vect.begin……
[/Quote]

安全是安全了,却完全没有必要。operator[]的效率比iterator的效率会低不少。

如果只是担心重新分配,你reserve()一下不就完了?

如果你还不放心,可以在DEBUG中加入验证语句,assert一下begin()始终不变,在release中去掉就好。
yilin57 2010-08-19
  • 打赏
  • 举报
回复
vector<SomeType> vect;
vector<DTrigulation> DT;//DTrigulation,自定义类,vect是其中一个成员
...
for(int i = 0; i < DT.size(); ++i)
{
DTrigulation test = DT[i];
SomeType start = test.vect.front();
SomeType end = test.vect.back();
for(int j = 0; j < test.vect.size(); ++j)
{
...
test.vect.erase(somevalue);
test.vect.push_back(SomeValue);
}
}
yilin57 2010-08-19
  • 打赏
  • 举报
回复
回复MasQua,学习了~谢谢啦
也谢谢大家~还是自己了解太少
AAA20090987 2010-08-18
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 huangyd33 的回复:]
引用 5 楼 arong1234 的回复:
你把start/end预先保存下来,然后在代码中继续使用时,由于vector已经被erase过了,start/end变量已经指向非法位置了,不能再继续使用


erase操作是修改性操作,所以先前的begin和end就会失效。在介绍vector的书中有详细的介绍。
[/Quote]

正解
独酌逸醉 2010-08-18
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 alwaysslh 的回复:]

代码没看,lz是这个意思吗:
C/C++ code

vector<SomeType> vect;
...
vector<SomeType>::iterator iter = vect.begin();
for(; iter != vect.end(); ++iter)
{
...
vect.push_back(SomeValue);
}



如果是这样,循环里的pus……
[/Quote]
点中要害。结贴吧!
yilin57 2010-08-18
  • 打赏
  • 举报
回复
可能之前没有说清楚
vector<SomeType> vect;
vector<DTrigulation> DT;//DTrigulation,自定义类,vect是其中一个成员
...
for(int i = 0; i < DT.size(); ++i)
{
DTrigulation test = DT[i];
SomeType start = test.vect.begin();
SomeType end = test.vect.end();
for(int j = 0; j < test.vect.size(); ++j)
{
...
test.vect.erase(somevalue);
test.vect.push_back(SomeValue);
}
}
还没有开始遍历内层vector的时候预存它的第一个和最后一个元素,每一个DTrigulation对应的vect不一样,不会对同一个vect的vector执行如下的赋值操作了:
SomeType start = test.vect.begin();
SomeType end = test.vect.end();
不知这样有什么问题么?
huangyd33 2010-08-17
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 arong1234 的回复:]
你把start/end预先保存下来,然后在代码中继续使用时,由于vector已经被erase过了,start/end变量已经指向非法位置了,不能再继续使用
[/Quote]

erase操作是修改性操作,所以先前的begin和end就会失效。在介绍vector的书中有详细的介绍。
yilin57 2010-08-16
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 arong1234 的回复:]
当然不影响。正因为不影响才错了,因为在循环中vector已经变了,而start,end却没有对应的变化到正确的值。你应该永远用vector.start()和vector.end得到开始和结束值,不能预先保存

引用 6 楼 yilin57 的回复:
那在循环之前存下来,循环中的操作还是会影响它的值么?
[/Quote]

我就是想用我对vector做改变之前的start和end的值,这样有问题么?
arong1234 2010-08-16
  • 打赏
  • 举报
回复
OK,应该是我错了,你保存的是“值”而不是“iterator”,对不住
arong1234 2010-08-16
  • 打赏
  • 举报
回复
当然不影响。正因为不影响才错了,因为在循环中vector已经变了,而start,end却没有对应的变化到正确的值。你应该永远用vector.start()和vector.end得到开始和结束值,不能预先保存[Quote=引用 6 楼 yilin57 的回复:]
那在循环之前存下来,循环中的操作还是会影响它的值么?
[/Quote]
yilin57 2010-08-16
  • 打赏
  • 举报
回复
呵呵~good idea
yilin57 2010-08-16
  • 打赏
  • 举报
回复
存入另外一个vector?
liutengfeigo 2010-08-16
  • 打赏
  • 举报
回复
赋值给宁外一个不是保存了?
yilin57 2010-08-16
  • 打赏
  • 举报
回复
请假,什么方式可以预先保留下来那两个值呢?
yilin57 2010-08-16
  • 打赏
  • 举报
回复
那在循环之前存下来,循环中的操作还是会影响它的值么?
arong1234 2010-08-16
  • 打赏
  • 举报
回复
你把start/end预先保存下来,然后在代码中继续使用时,由于vector已经被erase过了,start/end变量已经指向非法位置了,不能再继续使用
yilin57 2010-08-16
  • 打赏
  • 举报
回复

回复:AlwaysSLH
主要是进行了这样的操作:
start = *vect.begin();
end = vect[vect.size()-1];

for(; iter != vect.end(); ++iter)
{
...
vect.erase(remove(vect.begin(), vect.end(), start),vect.end());
...
vect.push_back(SomeValue);
}
vect.erase(remove(vect.begin(), vect.end(), start),end);
vect.push_back(SomeValue);
hastings 2010-08-16
  • 打赏
  • 举报
回复
LZ代码插错位置了,- -
AlwaysSLH 2010-08-16
  • 打赏
  • 举报
回复
代码没看,lz是这个意思吗:

vector<SomeType> vect;
...
vector<SomeType>::iterator iter = vect.begin();
for(; iter != vect.end(); ++iter)
{
...
vect.push_back(SomeValue);
}


如果是这样,循环里的push_back很可能造成vector容量不足,进而重新分配了内存,这样迭代器会失效
加载更多回复(1)

65,187

社区成员

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

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