4
std::vector<Foo> vec;
Foo foo(...);

assert(vec.size() == 0);
vec.reserve(100); // I've reserved 100 elems
vec[50] = foo; // but I haven't initialized any of them
// so am I assigning into uninitialized memory?

Is the above code safe?

1
  • 1
    Generally speaking, I tend to prefer at to operator[]. Although semantically identical and a bit longer to write, it does have the so-called bound-checking feature. I would never consider anything that write outside the boundaries as safe... Commented Mar 5, 2010 at 7:25

5 Answers 5

7

It's not valid. The vector has no elements, so you cannot access any element of them. You just reserved space for 100 elements (which means that it's guaranteed that no reallocation happens until over 100 elements have been inserted).

The fact is that you cannot resize the vector without also initializing the elements (even if just default initializing).

Sign up to request clarification or add additional context in comments.

Comments

4

You should use vec.resize(100) if you want to index-in right away.

vec[50] is only safe if 50 < vec.size(). reserve() doesn't change the size of a vector, but resize() does and constructs the contained type.

Comments

0

It won't work. While the container has 100 elements reserved, it still has 0 elements.

You need to insert elements in order to access that portion of memory. Like Jon-Eric said, resize() is the way to go.

Comments

0

std::vector::reserve(100) will claim 100*sizeof(Foo) of free memory, so that further insertion to a vector will not do a memory allocation until 100*sizeof(foo) is full, but accessing the element of that vector will give indeterministic content of that element, since its only claim the memory not allocate it.

Comments

0

Before you can use operator[] to access 50th element you should either call resize, push_back() something 50 times or use std::fill_n algorithm.

4 Comments

std::uninitialized_fill_n is no better than what he's doing.
You're right, fill_n() requires elements of vector to be intialized. But I guess std::generate() can be used instead.
No, generate with a simple function is no different from fill_n which isn't as close to what we want as uninitialized_fill_n. No generic algorithm will work here because STL algos change sequences, not containers. A back_insert_iterator would be a roundabout way of doing this, if you are set on using <algorithm>.
And again you're right. I guess I should be paying more attention to documentation and use stl more :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.