Доступ к членам объекта C ++ std :: vector перед инициализацией объекта - PullRequest
1 голос
/ 18 февраля 2020

Я только что понял, что могу получить доступ к членам объекта моего пустого списка векторов объектов. Я думал, что vector.reserve (nmb) просто резервирует необходимую память (вроде nmb * sizeof (object)).

#include <iostream>
#include <vector>



class Car {

    public: int tires = 4;

    Car(void) {
        std::cout << "Constructor of Car" << std::endl;
    }
};

int main()
{
    std::vector<Car> carList;
    carList.reserve(20);
    std::cout << "Car tires: " << carList[0].tires << std::endl;
    std::cout << "Now comes the emplace_back:" << std::endl;
    carList.emplace_back();
    std::cout << "Car tires: " << carList[0].tires << std::endl;

    //Car carArray[20];
    //std::cout << "Car tires: " << carArray[0].tires << std::endl;

    return 0;
}

дает мне:

Car tires: 0                                                                                                                                        
Now comes the emplace_back:                                                                                                                         
Constructor of Car                                                                                                                                  
Car tires: 4                                                                                                                                        

...Program finished with exit code 0 

Почему я могу получить доступ к членам еще не инициализированных объектов? Спасибо.

Ответы [ 2 ]

4 голосов
/ 18 февраля 2020

Поскольку operator[] не выполняет каких-либо проверок границ (а просто переводит в некоторую арифметику указателей c при компиляции оптимизированного двоичного файла). Это так, что std::vector может использоваться так же эффективно, как обычный массив * 1012. *

0, который вы прочитали, это то, что происходит в памяти, где вектор зарезервировал пространство в куче. Обратите внимание, что операционная система инициализирует память программы с 0 в качестве меры безопасности (поэтому вы не можете просмотреть старые данные). Если ваши приложения работают немного дольше и страницы перезагружаются, вы также можете наблюдать другие значения мусора.

Вместо этого вы можете попробовать at(), который проверит границы.

1 голос
/ 18 февраля 2020

Доступ к элементам std::vector вне его размера (не его емкости) имеет неопределенное поведение .

Неопределенное поведение означает, что нет никакой гарантии, что что-либо определенное c произойдет в общем. Что именно произойдет, будет зависеть от конкретной реализации компилятора и стандартной библиотеки.

@ypnos упомянул одно вероятное поведение, но (любое) другое поведение также было бы допустимо стандартом C ++ и возможно в зависимости от как именно стандартная библиотека реализует std::vector и как именно оптимизирует компилятор.

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