Потеря ссылок на объекты внутри контейнеров - PullRequest
0 голосов
/ 28 мая 2020

Я изо всех сил пытаюсь исправить кусок кода, хотя считаю, что знаю причину. Я много искал в 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 остаются прежними.

Из того, что я знаю и из того, что я понял здесь или здесь Я не могу получить ссылку на объект в стеке какой-либо функции (мой для l oop, например). Однако я считаю, что время жизни объекта в контейнере такое же, как и у самого контейнера. Это заставляет меня поверить, что все объекты I push_back() должны сохраняться через функцию pre_proccess и функцию, которая ее вызывает.

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Похоже, что вектор изменил размер сам, и его пришлось переместить (что сделает недействительными все ссылки на итераторы).

Попробуйте использовать 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";
}
1 голос
/ 28 мая 2020

push_back на векторе (может) сделать недействительной предыдущую ссылку / итератор.

это происходит в l oop там

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, чтобы избежать перераспределения (или изменить лог c).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...