C++ - value of uninitialized vector<int>

C++VectorScopeInitialization

C++ Problem Overview


I understand from the answer to this question that values of global/static uninitialized int will be 0. The answer to this one says that for vectors, the default constructor for the object type will be called.

I am unable to figure out - what happens when I have vector<int> v(10) in a local function. What is the default constructor for int? What if I have vector<int> v(10) declared globally?

What I am seeing is that vector<int> v(10) in a local function is resulting in variables being 0 - but I am not sure if that is just because of my compiler or is the fixed expected behaviour.

C++ Solutions


Solution 1 - C++

The zero initialization is specified in the standard as default zero initialization/value initialization for builtin types, primarily to support just this type of case in template use.

Note that this behavior is different from a local variable such as int x; which leaves the value uninitialized (as in the C language that behavior is inherited from).

Solution 2 - C++

It is not undefined behaviour, a vector automatically initialises all its elements. You can select a different default if you want.

The constructor is:

vector( size_type, T t = T() )

and for int, the default type (returned by int()) is 0.

In a local function this:

int x;

is not guaranteed to initialise the variable to 0.

int x = int();

would do so.

int x();

sadly does neither but declares a function.

Solution 3 - C++

The constructor you are using actually takes two arguments, the second of which is optional. Its declaration looks like this:

explicit vector(size_type n, const T& value = T())

The first argument is the number of elements to create in the vector initially; the second argument is the value to copy into each of those elements.

For any object type T, T() is called "value initialization." For numeric types, it gives you 0. For a class type with a default constructor, it gives you an object that has been default constructed using that constructor.

For more details on the "magic parentheses," I'd recommend reading Michael Burr's excellent answer to the question "Do the parentheses after the type name make a difference with new?" It discusses value initialization when used with new specifically, but for the most part is applicable to value initialization wherever else it can be used.

Solution 4 - C++

By default, vector elements are zero-initialized and not default-initialized. Those are two different but related concepts:

  • zero-initialization is what is done for static objects not having an explicit initialization and what is done for a member given in the initialized list with an initializer of (). For basic types, the value used is 0 converted to the type.

  • default-initialization is what is done for not explicitly initialized non static variables and members. For basic types it stay uninitialized.

(And C++0X introduces value-initialization which is still different).

Solution 5 - C++

As mentioned by others, what happens is the zero initialization kicks in. I actually use that a lot in my code (outside of vectors and other classes):

some_type my_var = some_type();

This allows me to make sure that my variables are always properly initialized since by default C/C++ do not initialize basic types (char, short, int, long, float, double, etc.)

Since C++11, you also can do so in your class definitions:

class MyClass
{
...
    int   my_field_ = 123;       // explicit initialization
    int   your_field_ = int();   // zero initialization
};

For vectors, the std library uses T(). Whatever T() is, it will use that default initialization. For a class, it calls the default constructor. For a basic type, it uses zero ('\0', 0, 0.0f, 0.0, nullptr`).

As mentioned by James McNellis and Nawaz, it is possible to set the value used to initialize the vector as in:

std::vector<int> foo(100, 1234);

That feature is also available when you resize your vector (if the vector shrinks, the default value is ignored):

foo.resize(200, 1234);

So that way you can have a default initialization value. However, it's a be tricky since you have to make sure that all your definitions and resize() calls use that default value. That's when you want to write your own class which ensures that the default value is always passed to the vector functions.

However, if you want to have a way to auto-initialize to a specific value, you can mix both features this way:

struct my_value {
    int   v = 123;
};

std::vector<my_value>  foo(100);

// here foo[n].v == 123 for n in [0, 100)

This is my preferred way of dealing with this issue (i.e. if I don't want zero by default). It's an extra .v, but much less prone to mistakes and you don't need to know of the default value when you create a vector of my_value.

Also, for those who think this will be slow, it won't. The struct is like syntactic sugar as far as C++ is concerned. One optimized, it will be exactly the same as a simple std::vector<int> foo(100, 123).

Solution 6 - C++

The default initialization for an int type is to initialize it to 0.

This is true of most (if not all) primitive types: char will initialize to (char)0 (or '\0' if you prefer), float will initialize to 0.0f, and any pointer initializes to NULL. For other types, the parameterless constructor is invoked.

In general, the default initialization should happen pretty much whenever you aren't able to specify a constructor (or choose not to).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionanonView Question on Stackoverflow
Solution 1 - C++Mark BView Answer on Stackoverflow
Solution 2 - C++CashCowView Answer on Stackoverflow
Solution 3 - C++James McNellisView Answer on Stackoverflow
Solution 4 - C++AProgrammerView Answer on Stackoverflow
Solution 5 - C++Alexis WilkeView Answer on Stackoverflow
Solution 6 - C++Platinum AzureView Answer on Stackoverflow