简体   繁体   中英

Accessing C++ std::vector object members before object initialization

I just realized that I can access object members of my empty object vector list. I thought vector.reserve(nmb) just reserves the required memory (kind of 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;
}

gives me:

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

...Program finished with exit code 0 

Why can I access members of not yet initialized objects? Thank you.

Because the operator[] does not do any boundary checks (and just translates to some pointer arithmetic when you compile an optimized binary). This is so std::vector can be as efficiently used as a plain C array.

The 0 that you read is just what happens to be in memory where the vector has reserved space on the heap. Note that the operating system initializes the program's memory with 0 as a security measure (so you cannot peek on old data). If your applications runs a bit longer and pages are recycled, you can also observe other garbage values.

You could try at() instead which will check for boundaries.

Accessing elements of a std::vector outside its size (not its capacity) has undefined behavior .

Undefined behavior means that there is no guarantee that anything specific will happen in general. What exactly happens will depend on the particular implementation of the compiler and the standard library.

One likely behavior was mentioned by @ypnos, but (any) other behavior would also be permissible by the C++ standard and possible depending on how exactly the standard library implements std::vector and how exactly the compiler optimizes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM