9.23 — An introduction to std::vector

In the previous lesson, we introduced std::array, which provides the functionality of C++’s built-in fixed arrays in a safer and more usable form.

Analogously, the C++ standard library provides functionality that makes working with dynamic arrays safer and easier. This functionality is named std::vector.

Unlike std::array, which closely follows the basic functionality of fixed arrays, std::vector comes with some additional tricks up its sleeves. These help make std::vector one of the most useful and versatile tools to have in your C++ toolkit.

An introduction to std::vector

Introduced in C++03, std::vector provides dynamic array functionality that handles its own memory management. This means you can create arrays that have their length set at run-time, without having to explicitly allocate and deallocate memory using new and delete. std::vector lives in the <vector> header.

Declaring a std::vector is simple:

Note that in both the uninitialized and initialized case, you do not need to include the array length at compile time. This is because std::vector will dynamically allocate memory for its contents as requested.

Just like std::array, accessing array elements can be done via the [] operator (which does no bounds checking) or the at() function (which does bounds checking):

In either case, if you request an element that is off the end of the array, the vector will not automatically resize.

As of C++11, you can also assign values to a std::vector using an initializer-list:

In this case, the vector will self-resize to match the number of elements provided.

Self-cleanup prevents memory leaks

When a vector variable goes out of scope, it automatically deallocates the memory it controls (if necessary). This is not only handy (as you don’t have to do it yourself), it also helps prevent memory leaks. Consider the following snippet:

If earlyExit is set to true, array will never be deallocated, and the memory will be leaked.

However, if array is a std::vector, this won’t happen, because the memory will be deallocated as soon as array goes out of scope (regardless of whether the function exits early or not). This makes std::vector much safer to use than doing your own memory allocation.

Vectors remember their length

Unlike built-in dynamic arrays, which don’t know the length of the array they are pointing to, std::vector keeps track of its length. We can ask for the vector’s length via the size() function:

The above example prints:

The length is: 5

Just like with std::array, size() returns a value of nested type size_type (full type in the above example would be std::vector<int>::size_type), which is an unsigned integer.

Resizing a vector

Resizing a built-in dynamically allocated array is complicated. Resizing a std::vector is as simple as calling the resize() function:

This prints:

The length is: 5
0 1 2 0 0

There are two things to note here. First, when we resized the vector, the existing element values were preserved! Second, new elements are initialized to the default value for the type (which is 0 for integers).

Vectors may be resized to be smaller:

This prints:

The length is: 3
0 1 2

Resizing a vector is computationally expensive, so you should strive to minimize the number of times you do so. If you need a vector with a specific number of elements but don’t know the values of the elements at the point of declaration, you can create a vector with default elements like so:

This prints:

0 0 0 0 0

We’ll talk about why direct and brace-initialization are treated differently in lesson 16.7 -- std::initializer_list. A rule of thumb is, if the type is some kind of list and you don’t want to initialize it with a list, use direct initialization.

Compacting bools

std::vector has another cool trick up its sleeves. There is a special implementation for std::vector of type bool that will compact 8 booleans into a byte! This happens behind the scenes, and doesn’t change how you use the std::vector.

This prints:

The length is: 5
1 0 0 1 1

More to come

Note that this is an introduction article intended to introduce the basics of std::vector. In lesson 10.11 -- std::vector capacity and stack behavior, we’ll cover some additional capabilities of std::vector, including the difference between a vector’s length and capacity, and take a deeper look into how std::vector handles memory allocation.


Because variables of type std::vector handle their own memory management (which helps prevent memory leaks), remember their length, and can be easily resized, we recommend using std::vector in most cases where dynamic arrays are needed.

9.24 -- Introduction to iterators
9.22 -- An introduction to std::array

234 comments to 9.23 — An introduction to std::vector

  • Ahmed Gurie

    Thanks again Alex, I tried the last option and it works.

    std::vector<int> array = { 9, 7, 5, 3, 1 };


  • Ahmed Gurie

    Dear Alex, I tried to test the first simple example in this tutorial, but I am receiving a compile time error.  IntelliSense: Expected a ';'. it says ';' is needed before the opining bracket '{'. all previous exercises where fine for me. what do you think is wrong with my compiler?

    • Alex

      Your compiler probably isn't C++11 compliant. You can try a few things:
      1) Turn on C++11 functionality, if your compiler supports it and just has it turned off (check your compiler settings)
      2) Upgrade to a C++11 compliant compiler
      3) You can try this line instead:

  • Haizreff

    Your tutorial is the best tutorial ever. I cant live without it.
    Thank you so much Alex I am in love with you.
    There is something I didn’t get though. I want to ask if there is anything wrong with this code

    Maybe I didn’t get what fixed mean because this compiles with no errors so why would I need std::vector. Sorry if I didn’t get it.
    //Sorry, English is not my first language

    • Haizreff

      I know this isnt available in old c++ versions and I know they become fixed after they are assigned a value at run time and cant be resized but am I missing anything?

    • Alex

      Defining an array with a non-compile-time-const length is called a "variable length array" -- something that is allowed in C99, but not in C++. However, because it is allowed in C99, some C++ compilers will allow it, even though it is non-compliant with C++ standards.

  • BestCPPTutorial

    Alex, how can I make a std::vector multidimensional?

    I want it to look like this and it should be allowed to resize it. So I can have 0 to 10 lines of x, y and z..

    x1 y1 z1
    x2 y2 z2
    x3 y3 z3
    x4 y4 z4

    I can't imagine how the statement would look like. Should I also use std::array? because the amount of elements per line in std::vector will always be 3.

    • BestCPPTutorial

      I have no access to an IDE right now, but i guess it would be something like this.

      std::vector<std::array<double, 3>> positionList;

      • Alex

        Yes, you could do something like this, but using a struct is better here since the struct makes your code easier to understand. Using a struct also makes things easier to extend later, if you want to add another member.

    • Alex

      You can do something like this:

      Now you have a std::vector of Points, and you can access them like this:

      • BestCPPTutorial

        Okay nice, thanks alot this makes sense to me. Maybe slowly I understand the idea behind using structs and classes( I haven't read about them yet). It looks like much better coding.

        By the way I just came back here with the question if this was possible and there is your answear already. In the next article there is some code where you do the same thing with manual memory allocation(on the "struct Student" if i remember right)... Since you told the reader to prefer std::vector..this would have been my question..

        So far it looks like this.

        I wonder if it is better to use char or int for the team status of an entity. In most cases there are only 2 teams/factions.


    I got serious problem....
    I thought that std::vector type can be used same as an array. Which means the variable itself is a pointer. For example, when we type "std::vector<std::string> testArray;", I thought "testArray" is a pointer to the memory that has been dynamically allocated.

    However, the result of the code below seems strange.

    the result is

    1 : first
    2 : second
    1 : second
    2 : first

    1 : first
    2 : second

    So how could I understand the std::vector??


      Oh, now I got it. I should deliver the function variable as a reference!

    • Alex

      Think of a std::vector like a struct, where one of the members of the struct is the pointer to the memory that has been dynamically allocated. Something like this:

      In this case, testArray isn't a pointer, but rather it contains a pointer.

      It's the same with std::vector -- it isn't a pointer itself, but rather, it contains one as a member.

      Once we get to chapter 8 (classes), you'll start getting a better understanding of what std::vector actually is.

  • Kattencrack Kledge

    In the line of code that you wrote in the tutorial:

    There's a little mistake in the code: the return type of the function is void, but the function is returning 0.

  • Darren

    Just a comment about nomenclature. The 'sizeof()' operator returns the memory consumption of the argument passed however, the STL container member function '.size()' returns the number of elements the object has. Is this not a little confusing when talking about the size of a container and the 'sizeof()' a container? On the one hand having a '.size()' function is quite intuitive and a rename of the sizeof() operator would have been wise. On the other hand 'sizeof()' was inherited from C so it ain't going to be changed any time soon, so why not have the '.size()' function renamed to '.length()', say? (My guess is that in geometry the length of a vector means its magnitude, whereas its "size" in this context relates to the number of dimensions it represents i.e. the number of elements).

    • Alex

      I have the same question: calling the size() function length() would have made a lot more sense. I presume they did this for consistency with other classes in the standard library.

      It's interesting to note that std::string has both a size() and a length() function that do the same thing. Why this wasn't extended to std::array and std::vector, I'm not sure.

  • Darren

    So a vector of bool containing 8 elements is stored as a single byte i.e. 8 bits. So I was wondering could we use a vector of bool as a bit flag to a function?

    So instead of having to do bit-wise ORs with individual flags as an argument to a function we could just pass in the vector of bool with the elements representing the different options having either a value of true (1) or false (0). I've written the following to illustrate what I mean:

    The enum items could have more descriptive names for an actual application. If we wanted to add more options at a later stage then we could just increase the size of the vector. Any code that deals with the vector can be written to automatically handle different sizes, so is this a plus for code maintainability?

    • Alex

      You could, but std::bitset might be a better choice for this use case. std::vector's strength is that it can be resized at runtime, but for bit flags you probably don't need that.

  • Elpidius

    In response to deepu's question (with the comment's link as a reference):

    Hi deepu,

    Your problem is that you've declared three _empty_ arrays of type std::vector (i.e. their size/length is 0), and have then tried to assign elements into them. The subscript operator won’t resize the arrays. Use the resize() function to resize the arrays before using the subscript operator.

    I've set the intial size/length of the arrays to 10,000, so we have elements to actually assign values to. Then when all our elements have been assigned a value, and our largest element is accessed, our arrays are resized larger by 10,000 (using a conditional statement). That way we never access an element out of range.

    I've never actually let the program run until it output 'ans' to the console, since it takes forever to calculate, but it should run fine. Except, there is a possibility that your array element's integer values may exceed 2,147,483,647. If that is the case declare your std::vector arrays as type 'long long'.

    Here is a functional version of your program:

  • Elpidius

    Hi Alex,

    Is it possible to iterate through a two-dimensional std::vector array using a for-each loop? If so, how?

    • Alex

      You'd have to use two for-each loops: one for the outer std::vector, and one for each inner std::vector:

  • Jim

    Wow Alex,
    This intro to std::vector was great.
    It make using them super easy.  However l don't understand the self cleaning to prevent memory leak at all.  Can you explained it in more detail.  I understand the allocation of memory for the array,  but get lost on the if statement.  

    Then why would you want to compact 8 bool's into a byte?   Unless you want to use them to supply parameters as arguments to a function. Could you tell us how you might use this?

    • Alex

      Just before a std::vector is destroyed, a special piece of code gets run that deallocates any memory the std::vector allocated for use during the time it was alive. That's why std::vectors are so nice -- you don't have to worry about memory allocation or deallocation -- std::vector handles all the details for you.

      In the example, the array is allocated some memory. But if the earlyExit boolean is true, then the function exits before the deallocation statement is ever run. And when the function goes out of scope, the local variable pointer pointing to the allocated memory goes out of scope and gets destroyed, leaving our allocated memory stranded (leaked).

      You'd want to compact 8 bools into a byte to save space. We talk about this in lesson 3.8 -- Bitwise operators.

  • Chris


    is there a way to declare size of vector when we declaring the vector? at above example we must to resize it to declare the size of vector.

    Thank you.

    p.s. finally i can comment now haha.. i must use vpn to do it..


    "std::vector has another cool trick up its sleeves. There is a special implementation for std::vector of type bool that will compact 8 booleans into a byte! This happens behind the scenes, and is largely transparent to you as a programmer."
    said in above, But i can't get the point what the exact meaning of that.

    Is that you mean??
    Thanks, Alex  _(:зゝ∠)_

    • Alex

      Getting the actual size of a std::vector is a little difficult since it does dynamic allocation, and sizeof() won't return that. But the general idea is that normally storing 8 booleans would take 8 bytes. However, under this special implementation, storing 8 booleans only takes 1 byte. So in both cases above, it would be 1 byte. However, 9 booleans would take 2 bytes.

  • Vegeta

    My lecturer said that if I know that the size of the array will never change, I should use dynamic array, because it's faster. But if the size can change then I should use vector. What do you think?

    • Alex

      If you know the size of the array won't change, and the array is relatively small, you should allocate a std::array non-dynamically. If the size of the array won't change, and the array is large, you should allocate a std::array dynamically. If the size of the array could change at runtime, you should allocate a std::vector.

      • Elpidius

        Hi Alex, what's the syntax to allocate a std::array dynamically?

        • Alex

          std::array<int, 5> *ptr = new std::array<int, 5>; // dynamically allocate a std::array of 5 integers

          • Elpidius

            Thanks. Although, I think you forgot something in relation to the 5 integers, were you meant to write:

            std::array<int, 5> *ptr = new std::array<int, 5>; // dynamically allocate a std::array of 5 integers

            That being said, is there any reason at all to use dynamic arrays built into the C++ language?

            • Alex

              Yes, I meant as you said -- the comment section ate my angle brackets because it thought they were HTML. :|

              If by "dynamic arrays" you mean explicit use of new and delete -- yes, absolutely, when you want fine-tuned control over memory allocation and deallocation. In cases where you don't care so much, other structures (like std::vector) are great.

              • Elpidius

                By "dynamic arrays built into the C++ language", I was meaning is there any reason to dynamically declare an array of type int[5]?

                int *ptr = new int[5];

                • Alex

                  Not really -- if you're going to do this, you might as well dynamically allocate a std::array, since it has more predictable behavior with no downsides.

          • Elpidius

            The pointer, 'ptr', above points to the array itself (since std::array does not decay into a pointer to the first element (of the array)). So by dereferencing the pointer, I can use a for-loop with this pointer.

            class std::array<int,5> *
            5 3 2 7 9

            This is very useful. Thanks again Alex!

  • Lokesh

    "std::vector lives in the <vector> heading."  -->  "std::vector lives in the <vector> header."

  • Javad

    Hi Alex,

    I am using Microsoft VS Premium 2013, and it seems that indexing a vector using [] does have range checking, as I get run-time errors when I use vi[1000] for vi defined as std::vector<int> vi(6).


  • deepu

    Thank you for this great tutorial . I am having a problem with this code -

    There are no syntax errors but there is a problem when I run this file .
    Can anyone find out what's wrong .
    Thanks in advance.

  • Gopal

    Thanks James. It will be helpful.

  • James

    something like this?

    • Gopal

      Hey James,

      Thanks for you example, but its more advance then my understanding as i am beginner to C++. Can you explain how this works? push.back() function i have encounter 1st time, so pl. can you explain that function also briefly?

      • James

        Alex may go into more detail on this in later sections. For now just know push.back() is how to append elements to the end of the vector.
        push_back() and size() are member functions of vector.

  • Gopal


    Can we also define two (or more) dimensional array with std::vector?

    • Alex

      You can by creating a std::vector of std::vectors. The syntax for doing so is a bit tricky:

      If you want to preset the vector's size, you can do so like this:

      In C++11, you can also create/initialize it via uniform initialization:

      • Gopal

        A little bit weird but This seems helpful. Thanks.

      • Elpidius

        Hi Alex,
        Is it possible to access the elements of a two-dimensional std::vector array using the at() function? If so, how?

        • Alex

          With a std::vector of std::vectors, the first at() call will return a std::vector, so you should be able to call at() again on that:

          • Elpidius

            Thanks! After playing around with the subscript operator and the at() function, I've realised you can use a combination of the two to access the element of the inner vector.

  • James

    have question about vector "out of range error".
    following code will give me a range error when compiled and run in Visual Studio 2015 community
    but GNU cmd compile and ran using gcc 5.2.0 will not give an error.
    What am I missing?

    • James

      May have answered own question with little more digging found can use instead of V[i] use for range checking.
      now both compilers are consistent, but with different cryptic out of range error reporting.

      • Alex

        Yes, just like with built-in arrays, the subscript operator doesn't do any range checking.

        If you want runtime range checking with std::array or std::vector, use the at() function. Do note that this comes with a performance cost since it's extra logic that has to be executed with every call.

        • James

          Guess experience and good planning = better performance and efficiency.  Novices like myself should probably play it safe and take the performance hit?

          • Alex

            If you're a novice, you're probably better off using at(), at least until you really get the hang of how C++ works. Most new programmers worry too much about performance when it's not needed for what they're doing.

            Once you become more comfortable with arrays and C++ in general, whether you use at() or [] is a matter of comfort and context. For example, if you're asking the user to input an index and then manually checking to ensure it's in range, there's no need to call at() instead of [] since you've already done the work to ensure it's in range. There are plenty of cases where you can reasonably assume your index is in range.

            You could also write your initial program using at() and then optimize later once you're sure it's working by switching to [].

            • James

              great discussion. Thanks for the advice.
              Interesting how VS2015 must take the conservative approach sense it flagged my original code as a runtime error. And GNU GCC has different philosophy in programmer should check and find potential error.

  • Sam

    Could you please explain the iteration for the below loop. Also why is it called foreach loop and doesn't without keyword foreach? (sorry if its not a great question but as a newbie i quite did not understand the loop's iteration)


    • Alex

      Sure. This loops through each element of the array represented by variable array. For each iteration, a const reference named element references the current array element (allowing us to access the element being iterated over). The auto keyword ensures that element matches the type of array's elements.

      We then print out the value of that element.

      So for example, if array is an array of integers, this would print out the value of each of the integers in the array.

      It's called a for-each loop because it was named that in other languages that implemented it before C++. For simplicity, C++ tries to keep new keywords to a minimum, so they decided to reuse the for keyword rather than introduce a new 'each' keyword.

  • rob

    In the "compacting bools" section, if each element of the vector is taking up only a single bit, wouldn't using the "&" to find and display their individual addresses return a single address location?  This isn't the case for me but I am probably missing something.  Thanks.

    • Alex

      The way the boolean version of std::vector works behind the scenes is pretty complicated. When you use the subscript operator ([]), it returns an object that proxies the behavior of references to the individual bit. If you were to use the address-of operator (&) on this proxy reference, I think you'd end up getting it's address rather than the address of the byte containing the individual bit.

  • Aditya Patil

    I had not looked at the website for few months and now I see so much new stuff. Not to mention that everything is as clearly explained as ever.

    great work! I hope you will continue to add tutorials on more topics. I guess the one that are most needed are those on the imp library features like various containers.

    • Rob G.

      Hi Alex I did fine with vectors but then I had a sudden blank on what we have already covered -- I think. In the code below is it correct that int * array = pointer to an array? If so what is the array called (new int[.]{....}) doesn't say. Could u please rclariofy this remidial question. I understand every new must have a delete. In delete[]foo is the array pointer undergoing deletion?

      • Alex

        Yes, it's fine to set an int pointer to point at an int array. The dynamically allocated array doesn't have a name (and it doesn't need one since you access it through the pointer).

        Assuming the code represented by ... doesn't terminate the program or cause an infinite loop, your delete[] foo is called, which will return the memory being pointed to back to the operating system.

    • Rob G.

      Alex, sorry, I have a remedial question prompted by the vector exercise. Not with vectors but a sudden blank on the following:

      It seems a pointer to an array has been created (n_ptr) but the array has no name.
      When its deleted, is the pointer n_ptr being deleted?

      • Alex

        Deleting the pointer doesn't actually delete the variable. It returns the memory pointed to by the pointer back to the operating system, so it can be reassigned.

  • Achsaf

    Really great and comprehensive, I just have one question. Why not use vectors in all the cases where an array is needed? It appears to take care of everything.

    • Alex

      Vectors have some additional performance overhead. The short answer is: use vectors if array-resizing is needed or the array size isn't known at compile-time. Otherwise, use std::array.

  • Quang

    Dear Alex, I’m having a problem here hope you can help me out

    #include <iostream>
    #include <vector>

    using namespace std;

    int main ()
        vector < long long > arr;
        arr [ 0 ] = 1;
        arr [ 1 ] = 2;
        long long sum = 0;
        int i = 2;
            arr [ i ] = arr [ i - 1 ] + arr [ i - 2 ];
            if ( arr [ i ] % 2 == 0 )
                sum += arr [ i ];
        while ( arr [ i ] < 4000000 );
        cout << sum << endl;
        return 0;

    I’ve been trying a lot of experiment ( by put // in evry single line ) and it seemed that the problem might in line arr [ 0 ] = 1; ( may be also the next line ). The compiler seems crashing or something like that, I don’t know how to fix it!! Thank you Alex..

    • Devashish

      You only have declared the vector. You never allocate memory for it's elements (e.g. didn't initialize the vector or resizing it). I think that's the problem. Alex can help you better because it seems to me like while's condition also needs to be changed. I am also curious to know if there are other issues with this vector.

      • Alex

        Yup, you've declared an empty vector and then tried to stick elements into it. The subscript operator won't resize the array. Use the resize() function to resize the array before using the subscript operator.

        • Quang

          Thanks for your answer but I think I still don't know why we have to resize and how can we resize because in this example, I don't know exactly how many index there are? ( cuz I don't know how many terms in the Fibonacci sequence whose value is less than 4000000, and it will be costly if I write a function to count the terms! ) It seems to be uncleared to me...

          • Alex

            Well, it looks like you're trying to implement an iterative version of the Fibonacci sequence. I agree, I don't know how many indexes there are either until that sequence reaches 4 million.

            You can do one of a few things:
            1) Resize vector to something really large (e.g. 10000), run your program once, and see how many indexes it needs, and then change the program to allocate that many for future runs. That'll work as long as you don't change the 4 million condition.

            2) Don't use vector in the way that I've shown you above. The use above is appropriate when you know how many elements you need, or can set an upper bound. But in this case, you don't really know in advance either of these things. So using vector the way you're trying to do so is inappropriate. What you _really_ want is something that will continue to grow as you put elements into it.

            Fortunately, vector can do that too! I didn't show how in this lesson, because it's a little more complicated, and I haven't talked about stacks yet. However, instead of doing this:

            You can do this:

            This will add a new element to the end of the array with the value of the previous two elements. It will also resize the vector if necessary.

            Of course, you'll still need to set the length of the vector to at least 2 elements before the loop so you can set the values of arr[0] and arr[1].

            • Quang

              It works now Alex ! Thank you so much

            • J3ANP3T3R

              Question time ! :>

              so like vector arrays automatically resizes itself as needed ... but why the need to manually resize the vector array ?

              • Alex

                Vectors don't resize as needed in all cases (e.g. if you call operator[] with an index of 100, the std::vector won't grow to 100 elements). But they do have the capability to resize, either at your request, or automatically in some cases (which we'll talk more about in chapter 7).

                It can be more efficient to manually resize the vector ahead of time if you know how big it is. Let's say we wanted to create a vector of size 100. If we tell the vector to create 100 elements, it can do that all in one go before we assign any values to it. That's fast. However, if we start with a 0 sized vector and just start adding elements, it may grow from size 0 to 1, then 1 to 2, then 2 to 4, then 4 to 8, then 8 to 16, then 16 to 32, then 32 to 64, then 64 to 128, each time requiring copying a bunch of the elements from the old memory to the new memory. That's slow.

                In general, if you're using a vector like an array, you should pre-size it.

                • Vlad

                  It's probably too late now, but the index of a Fibonacci number is, according to :

                  So, for this case, a "double dIndex" can be initialized and then used as array.resize( static_cast<int>(dIndex) ).

  • Waves

    Hey Alex. Great work! I have a question.
    In the line:

    why do you use "&element" instead of "element" which was what is stated in the for each loops section?

    • Alex

      Let's examine two related cases:

      In this case, element is a normal variable, which means element will be a _copy_ of the current array element being iterated over.

      In this case, element is a reference variable, which means element will refer to the actual array element being iterated over.

      In almost all cases, it makes more sense to use a (const) reference in a for-each loop because making a copy is extraneous and hurts performance.

  • Nguyen Van Duong

    Can you update more about STL library.Thanks so much.!

  • Len

    Yes!  Anything to make memory allocation easier (memory leaks still concern me somewhat).

    One somewhat confusing aspect of the above examples is the use of i.e. the name "array2" rather than the name "vector2".

  • George

    Wow, great! Thanks. I was really waiting for this article and have just found out that you managed to finish it!

    Would be really cool to have Comprehensive quiz for chapter 6 also!

Leave a Comment

Put all code inside code tags: [code]your code here[/code]