对象在容器中的生命周期及其引用

问题描述 投票:0回答:2

尽管我相信我知道原因,但我仍在努力修复一段代码。我确实在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更改为LINEY。尤其是,pts和segs保持不变。

[根据我所知道的以及对herehere的了解,我无法获得任何函数堆栈上的对象的引用(例如,我的for循环)。但是,我相信对象在容器上的生命周期与容器本身相同。它使我相信,push_back()的所有对象都应通过函数pre_proccess和调用它的函数来保留。

c++ c++11 pass-by-reference
2个回答
0
投票

向量(可能)上的[push_back使先前的引用/迭代器无效。

它发生在循环中

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足够的位置,以避免重新分配(或更改逻辑)。


0
投票

看起来矢量会自行调整大小,因此必须重新放置(这将使所有迭代器引用无效。)>

在处理之前尝试使用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";
}
© www.soinside.com 2019 - 2024. All rights reserved.