我正在努力修复一段代码,尽管我相信我知道原因。我在Stack Overflow上搜索了很多,很多人都有类似的问题(并且提供了很好的答案),但我仍然不确定我是否理解我的代码的问题。
我试着举了一个比较小的例子,但是我的结构本身就不简单。我希望下面的内容足够简单。
我在摘录上的目标。
有一个点的向量
有一个段的向量。(其端点是指上面向量中的点)
有一个事件的向量。(保持对现有段和点的参考)
segment::segment (point &pt1, point&pt2, int i) {
s = &pt1; e = &pt2; ind = i; // point *s, point *e, int ind
}
event::event (segment &s, point &pt, int tp) {
seg = &s; type = tp; p = &pt; //segment *seg, int type, point *p
}
void pre_process (int size, std::vector<point>& pts, std::vector<event>& evts,
std::vector<segment>& segs) {
float x, y;
for (int i = 0; i < size; ++ i) {
std::cin >> x >> y;
pts.push_back({x,y});
}
for (int i = 0; i < size; ++i) {
int j = (i+1)%size;
if (cmpXY(pts[i], pts[j]))
segs.push_back({pts[i], pts[j], i});
else
segs.push_back({pts[j], pts[i], i});
evts.push_back({segs[i], *segs[i].s, 0});
evts.push_back({segs[i], *segs[i].e, 1});
std::cout << 2*i << "\n";
std::cout << segs[i].s << "\n"; //ALWAYS EQUAl
std::cout << evts[2*i].seg->s << "\n";
} // LINE X
for (int i = 0; i < size; ++i) { //LINE Y
std::cout << 2*i << "\n";
std::cout << segs[i].s << "\n"; //DIFFERENT SOMETIMES
std::cout << evts[2*i].seg->s << "\n";
}
所以,问题是我的对象指向的一些地址从LINE X变成了LINE Y,尤其是pts和segs保持不变。
根据我所知道的和我所理解的 此处 或 此处 我无法获得任何函数(例如我的for循环)堆栈上的对象的引用。然而,我相信容器上的对象的寿命和容器本身是一样的。这让我相信,所有的对象我 push_back()
应该在函数pre_proccess和调用它的函数中持续存在。
push_back
在向量上(可能)使之前的引用iterator无效。
它发生在那里的循环中
if (cmpXY(pts[i], pts[j]))
segs.push_back({pts[i], pts[j], i});
else
segs.push_back({pts[j], pts[i], i});
evts.push_back({segs[i], *segs[i].s, 0});
你必须 reserve
够用 segs
以避免重新分配(或改变逻辑)。
看起来是向量自己调整了大小,不得不重新定位(这将使所有迭代器引用无效)。
尝试使用 std::vector::reserve
在处理前。
void pre_process (int size, std::vector<point>& pts, std::vector<event>& evts,
std::vector<segment>& segs) {
pts.reserve(size);
evts.reserve(size);
segs.reserve(size);
float x, y;
for (int i = 0; i < size; ++ i) {
std::cin >> x >> y;
pts.push_back({x,y});
}
for (int i = 0; i < size; ++i) {
int j = (i+1)%size;
if (cmpXY(pts[i], pts[j]))
segs.push_back({pts[i], pts[j], i});
else
segs.push_back({pts[j], pts[i], i});
evts.push_back({segs[i], *segs[i].s, 0});
evts.push_back({segs[i], *segs[i].e, 1});
std::cout << 2*i << "\n";
std::cout << segs[i].s << "\n"; //ALWAYS EQUAl
std::cout << evts[2*i].seg->s << "\n";
} // LINE X
for (int i = 0; i < size; ++i) { //LINE Y
std::cout << 2*i << "\n";
std::cout << segs[i].s << "\n"; //DIFFERENT SOMETIMES
std::cout << evts[2*i].seg->s << "\n";
}