cmourglia
cmourglia

Reputation: 2534

std::vector difference of behaviour between msvc and gcc on operator[] after reserve, which is right?

This snippet of code fails miserably using msvc (out of bound error) but appears to work fine with both gcc and clang. What is the correct behaviour ?

#include <iostream>
#include <vector>

int main() {
    std::vector<int> v;
    v.reserve(10);
    for (int i = 0; i < 10; ++i)
    {
        v[i] = i * 2;
    }

    for (int i = 0; i < 10; ++i)
    {
        std::cout << v[i] <<  " ";
    }
    std::cout << std::endl;

    return 0;
}

Upvotes: 5

Views: 436

Answers (2)

Hayt
Hayt

Reputation: 5370

Some explanation on what is undefined here:

std::vector<int> v;
v.reserve(10);

reserve only "reserves" memory but does not actually change the size of the vector. So when you do

v[i] = i * 2;

You write an int to a place which was not initialized yet because the vector has still the size 0.

What happens in those cases is undefined. Compilers and library implementations here are free to do what they like.

What is defined though is that the size of the vector does not change by reserve (but by resize) but the capacity (which is something different).

Upvotes: 3

krzaq
krzaq

Reputation: 16431

The behavior is undefined. reserve only reserves memory, but doesn't affect the size of the container. Maybe you wanted to use resize?

std::vector<int> v;
v.resize(10);
for (int i = 0; i < 10; ++i)
{
    v[i] = i * 2;
}

though in this case you could've written

std::vector<int> v(10);
for (int i = 0; i < 10; ++i)
{
    v[i] = i * 2;
}

Alternatively, you could use reserve in concert with push_back:

std::vector<int> v;
v.reserve(10);
for (int i = 0; i < 10; ++i)
{
    v.push_back(i * 2);
}

Upvotes: 7

Related Questions