Доступ к вектору с индексом 0, когда он пуст - PullRequest
2 голосов
/ 29 марта 2020

Почему я все еще могу получить значение из vectors[0], даже если я уже pop_back() на первом шаге?
Я предполагаю, что теперь мой vectors пуст и проверьте его, вызвав empty()

#include <iostream>
#include <vector>

struct Vector2 {
    int x, y;

    Vector2(int _x, int _y)
        : x(_x)
        , y(_y) {}

    Vector2(const Vector2& vec)
        : x(vec.x)
        , y(vec.y) {
        std::cout << "[Copy] Vector2{" << x << "," << y << "} copied!"
                  << std::endl;
    }

    void Print() {
        std::cout << "[Print] Vector2{" << x << "," << y << "}" << std::endl;
    }
};

void PrintVectors(const std::vector<Vector2>& vectors) {
    std::cout << "---" << std::endl;
    for (auto& vector : vectors) {
        std::cout << "Vector2{" << vector.x << "," << vector.y << "}"
                  << std::endl;
    }
}

int main() {
    std::vector<Vector2> vectors;
    vectors.push_back({21, 78});

    PrintVectors(vectors);

    // First
    vectors.pop_back();
    if (vectors.empty()) {
        std::cout << "Empty condition!" << std::endl;
    }
    vectors[0].Print(); // ---> I thought I'd get an error at this point.
    vectors.insert(vectors.begin(), {vectors[0].x + 1, vectors[0].y});
    PrintVectors(vectors);

    // Second
    vectors.pop_back();
    vectors[0].Print();
    vectors.insert(vectors.begin(), {vectors[0].x + 1, vectors[0].y});
    PrintVectors(vectors);

    // Third + no pop_back needed
    vectors[0].Print();
    vectors.insert(vectors.begin(), {vectors[0].x + 1, vectors[0].y});
    PrintVectors(vectors);

    // 4th
    vectors.pop_back();
    vectors[0].Print();
    vectors.insert(vectors.begin(), {vectors[0].x + 1, vectors[0].y});
    PrintVectors(vectors);
}

Тогда это условие позволило мне отладить через gdb . Я вижу, что значение _M_ меняется, но я понятия не имею, что происходит (я не вижу закономерности или отношения между _M_start и _M_finish).

1 Ответ

4 голосов
/ 29 марта 2020

Доступ к пустому вектору с индексом 0 с помощью operator[] выходит за границы и, таким образом, неопределенное поведение и выполнение этого делает всю программу недействительной. Компилятору разрешено генерировать любой желаемый результат. Любое поведение приемлемо. Вы не можете рассуждать о программах, содержащих UB.

...