10.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:

The length is: 5
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 11.9 -- 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.

10.24 -- Introduction to iterators
10.22 -- An introduction to std::array

244 comments to 10.23 — An introduction to std::vector

  • yeokaiwei

    Hi Alex,
    Is std::vector named because it writes to the vector register?

    "Vector registers are the storage areas in a CPU core that contain the operands for vector computations, as well as the results. The size of the vector registers determines the level of SIMD instructions that can be supported by a given processor's CPUs."

  • Josh

    Hi, if I do the following:

    This outputs:

    Do you know why this is? Does this mean each Vector element in this case is 3 bytes in size?

    Also, is there any way to actually 'see' the boolean compacting in action? (this is what I was trying to use sizeof() for).

    • nascardriver

      You're using `sizeof(bool)`, I suppose you meant `sizeof(booleanCompacting)`.
      `sizeof()` doesn't care about variables, it operates on types.
      `sizeof(booleanCompacting)` is identical to `sizeof(std::vector<tbool>)`, the elements have no effect.

      The easier solution to seeing how much dynamic memory a vector occupies is to look at the disassembly.
      Given this code

      The compiler (With tweaked optimizations, showing only the relevant part) generates (Numbers are decimal)

      `mov edi, XX` means "move the value XX into the register edi" (You can think of registers as variables).
      `edi` is the argument that is passed to `new`, it's the size in bytes of the memory that should be allocated.
      For `std::vector<int>`, 400 bytes are allocated. This is intuitive, 100 * sizeof(int) = 400.
      For `std::vector, only 16 bytes are allocated. 16 bytes are 128 bits, meaning 28 bits (~4 bytes) are unused. This is because `std::vector` usually grows exponentially (1, 2, 4, 8, 16, 32, ... bytes).

      You can play around with this example here

      If you want to to see vector sizes without disassembling, you can use a custom allocator and log how much memory is being allocated. I won't go into detail, you'll learn some of these things later.
      An allocator is a type that assists with memory allocations and permits overriding how the allocations work. `std::vector` by default uses `std::allocator`, which calls `new` to allocate memory. A common use case for custom allocators in `std::vector` is to provide an allocator that doesn't perform dynamic allocations, because those are slow (`std::pmr::vector`).
      We can give `std::vector` a custom allocator, which is also a `std::allocator` (meaning it uses `new`), but before performing the allocation, logs how many bytes will be allocated.


      allocating 400 byte(s)
      allocating 16 byte(s)

      You can play around with this at or on your computer

      EDIT: Your 24 comes from a vector containing
      - Pointer to begin (8 bytes)
      - Pointer past the last element (8 bytes)
      - Pointer to end of allocated memory (8 bytes)
      - Pointer to begin (8 bytes)
      - Length (8 bytes)
      - Capacity (8 bytes)

      • Josh

        Hi, thanks for the reply! Sorry, I did mean to use `booleanCompacting` rather than `bool`. This is a really interesting topic, I'll be sure to look into it further. Thanks for providing the links to the disassembly

  • Forhad Rahman

    A small fix, gentlemen -

    At 'Resizing a Vector' section, you wrote(the last snippet):

    This code is okay. But in output, you wrote:
    > This prints:

    > 5
    > 0 0 0 0 0

    It would be:
    > This prints:

    > The length is: 5 // Here, add the strings.
    > 0 0 0 0 0

    Thanks for this wonderful site :)

  • Knight

    Can someone explain this? How if (earlyExit) related int *array{ new int[5] { 9, 7, 5, 3, 1 } };?

  • Andrew Johnson

    Could I make a suggestion.  In the examples you use a variable named array.  The linter - or whatever is formatting the code - looks like it is treating that as a keyword and colouring it purple/pink instead of black like other variables.  For example, see the example where you use array, array2 and array3.  I keep misreading an actual C++ keyword and then having to remind myself it is in fact a variable: changing the variable from array to anArray or array1 would improve clarity I think.  Make it easier to scan the code at least.

    • Andrew Johnson

      I meant to add that it's especially confusing when considering std::array which is a Type rather than a variable and thus should be purple/pink (or at least distinguished from standard variables.)

  • Jasper

    Could anyone explain how std::vector manages to deallocate itself as soon as it goes out of scope?

  • Sahil

    In the vectors remember their length section, in the following line of code the '&' should be next to the variable name and not the variable type since its a reference to a std::vector and not a reference variable.

  • Berrie

    In the more to come section it states the following:
    "In lesson 7.10, we’ll cover some additional capabilities of std::vector"

    Since this is the introduction and this is chapter 9.23 I don't think the 7.10 is correct. I believe this should refer to chapter "10.11 std::vector capacity and stack behavior".

    I could be wrong because this is as far as I got into the course.

  • NewBeginner

    Glory to God now I can use C++ vectors.

    I read this page (thank you and also used and .

    If I get help with condensing the following (previous post) thank you.

  • NewBeginner

    I have a 10 by 10 grid that I want to use for a game and I have the following that I have written. It has become complicated. Now I want to use vectors in simplifying this code.

    I have been studying vectors and arrays. I tried using arrays and it became so complicated that I am now trying to use vectors.

    I can set up my WinMain and use CreateWindowExW to put text into for seeing a report of what I am doing. I can do that. I do not want to use CLI. I want help with placing the following into vectors and simplifying the code.

    Would you please clean this up and use vectors? I can then try to use your logic further in the program.

    C++11 please.

    I want to be able to expand this to a larger size maybe 50 by 50, or 100 by 100, etc. Thus I want to automate it and not have to write out every one of the lines again and again.

    Thank you.

    Thank you.

  • J34NP3T3R

    1.) can a vector parameter ommit type ?

    2.) can we now just focus on using std::vector for array rather than the other array types ?
    it seems like std::vector is the jack of all trades.

    3.) "In lesson 7.10, we’ll cover some additional capabilities of std::vector"
        is this a typo ? lesson 7.10 is about break / continue

  • Pieter-Paul Strybol

    HI all,

    I had a question about the dynamic memory allocation behavior of vectors. If they are the equivalent of

    does that mean ALL vectors are automatically stored on the heap? If so, there would be no need to ever use the 'new' keyword in combination with vectors or strings, correct?

    Can anyone help me answer this?

    Thanks in advance!

  • kio

    Alex, can you put creating comments on the top of the "comments section", It's a bit painful to scroll to the down of the list every time :D
    I have changed my mind -> it's better this way, so you can study other comments before asking duplicated question.

    You need to update the following line,
    ". In lesson 7.10, 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."
    7.10 is not existing anymore in terms of std::vector.

    Is this compact boolean, similar to the bitwise?, just a bit advanced version.

  • Hey there, so I was working on a project and I what I did was I created a function with `int` as the return type and at the end I had to return a vector. I return the vector and it was showing errors. So what did I do next? I used my creativity and instead of using `int` as the function return type I used `std::vector<int>` and then I return the vector and it worked. Now the problem is although it works fine I feel it's not a good way or should I say it's a bad practice or something

    Here's a sample of how it looks like at first:

    But it didn't work

    Then I modified to this:

    And surprisingly enough it works but my main question is can this be done and should it be something I can do or something I should never do?

  • Pretty cool stuff. I've manually coded large bitfields and it's a bit of a pain. Looking forward to using the bool case of std::vector. Are there any limits on how long such an array can be?

  • Sahil

    We know that return by reference or address can be useful when working with dynamically allocated data. However,

    1: Why did nothing get output?
    2: why I got warning below while memory is generated dynamically for vectors so returning them from withing a function to the main shouldn't be an issue?

    " returning address of local variable or temporary: array"
    3: for every iteration, does test(10) is called or it is called just once?

    • nascardriver

      `test(10)` is only called once.

      It doesn't matter how `std::vector` works, you're returning a reference to a local variable with automatic storage duration. The vector dies at the end of `test` and there's nothing you can do about it.
      If you want to return it, return it by value.

      Your vector `array` will be copied (not really, but let's call it a copy for now) to the caller.

  • Rock

    "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!"

    Would you please clarify this more? Why is this considered to be a cool feature?
    I ran the code below, and gave me '48' for the size of the array. why?

  • passionate_programmer

    >> no need to specify length at initialization

    Did you mean at declaration?

  • Tim

    In the previous lesson, you said that std::array should always be passed by reference or const reference.

    Does the same apply to std::vector?

  • choofe

    Hi. I have a question about vectors. It is confusing me.
    Is it possible to declare a 2 dimension vector of 2 dimension vectors of int (any fundamental type -for now). It is possible using initialization with lists or predefined vectors of known size to create the desirable size (the result would be constant in size of the predefined one and have to change the predefined vector for each size).
    But I want to create a non zero size like this:
    array of int (M(SxP)xN(SxP))
    M,N,S,P are not known at the compile time.
    For a better picture , imagine a classic sodoku puzzle with 9 houses in 3x3 grid which each house has 9 cells in 3x3 grid (containing 1~9).
    I tried this (and many other syntaxes).Here All M,N,S and P are 3.

    I wonder what do I missed? I know I can make it happen with a temporary board_t like:

    but I prefer using unknown object.
    In the other hand I know how to use resize() in favor to resize vectors to desirable sizes after creating an empty zero sized one. But isn't it more faster to make this happen at the declaration rather than doing additional processes? because I just want an empty vector!
    In case of some encapsulation and class solution to this I just want to know is there a single line declaration to this? Or instead of the complex single line I should go with resize(). As I have seen many times you mentioned that "Resizing a vector is computationally expensive, so you should strive to minimize the number of times you do so."

    • nascardriver

      The more dimensions you add, the harder it gets to work with it. You'll probably you it easier if you reduce your dimensions to 1 or 2.

      At @a, you say that @b is a `board_t`. A `board_t` is a `vector>`, but @b is a `vector`.

      The rest of the code won't get much better. You can do sudoku just as well in a 1-dimensional vector.

      • choofe

        This is fun. Because at no one could answer this!
        someone even told that this is illegal after c++11
        I just wanted not to bother you! as I know you have much comments to answer!
        Thank you.

  • Fan

    Regarding std::vector<bool>, I have heard advice against its use, and I found an innocuous-looking piece of code that breaks:

    So what's your take on using std::vector<bool>?

  • hausevult

    When I saw that std::vector resizes arrays for you, I wanted to test how I could do this using built-in dynamically allocated arrays. However, before I could even get there, I ran into an odd issue with using references to refer to a dynamically allocated array!

    (Note that I am using const pointers to const values as parameters, which is kind of error-prone and annoying to write)
    (Note #2 because this is kind of unclear: the above example works, but is awkward)

    As you can see, I am trying to call printDynArray() by passing in a pointer to my array "array" and a pointer to the length of that array, "array_length". However, the intention of reference variables is to alleviate the awkward syntax of using pointers as function parameters, though I am quite unsure as to how I can reference a dynamically allocated array at all! I have seen in lesson 6.11 how you can reference a built-in fixed array, though. Am I overlooking something here?

    Here is my attempt at accomplishing the same effect using references for the parameters of printDynArray()

    However, I seem to get the following error:

    I am not exactly sure what the compiler is telling me here... Nowhere do I attempt to initialize a non-const reference with an r-value of type "const int*"! This is quite strange. From this, I take it that references cannot reference pointers? Not sure where to go from here testing this...

    • nascardriver

      Dynamically allocated arrays are just pointers. All you can do is use a reference to a pointer, which doesn't make sense if you also use `const`.

      Your problem is that you're trying to have a reference to a `const int*`, but you're passing in an `int*`.
      Instead of making the pointer `const`, you can make the reference `const` (Or both).

      So, stick with `const int*`.

      • hausevult

        Thank you! I read that incorrectly, I had thought the following:

        Whereas the correct a const reference to a non-const pointer is actually:

        This is because the type of variable being referenced, 'int*', must be written to the left of the type and initialization of the reference itself.
        I now fully understand this. Thank you so much for your dedication =)

      • hausevult

        Now for what I had intended to do initially- manually resizing a dynamically allocated array.
        Here is my working code!

        This prints the following:


        • nascardriver

          Good job! We do this later when you get to classes, you'll have a head-start then :)
          `new_length` and `array_length` shouldn't be passed by reference. They're built-in types. Passing them by value is faster.

          • koe

            It seems you can make a strange kind of global variable

            Pointers passed in there can access y.

        • koe

          This will run into trouble if the new length is shorter than original length, so use std::min().

      • koe

        Instead of:

        do you mean this?

        I tested, and you can point 'array' at a different variable here using 'd', but cant change the value pointed to. So the next one would would be:

        If a pointer should be treated as const then it would have to be a 'const reference', so saying 'const pointer' doesn't add any information.

  • Ryan

    Just wanted to ask that under Vectors remember their length, why are we passing /const std::vector<int>& array/ into the funtion with the & symbol?

    Does this mean we are passing the address of the vector array... which is the first element?

    • nascardriver


      It means we're passing a reference to the vector (Which is its address). This doesn't change how the vector is accessed and what its value is. It's still a vector. Passing non-fundamental types by reference is usually faster than passing them by value.
      Const reference parameters were introduced in lesson 6.11a and are further elaborated in lesson F.7.3.

  • Sid22

    Recently learned about brace brace initialization and vectors so playing around with both.
    This code is not printing the float values of the

    objects. Can't understand why?

  • Sriram M R

    Under Resizing a vector there is a error in the code in line 7 of

    Instead of array.size() shouldn't we use vec.size()

  • Ryan

    In very large programs, does bound checking increase compile time significantly or is it just a minor issue?

    • nascardriver

      Compile time shouldn't bother you, the user of your software isn't affected by it.
      Bounds checking via `at` doesn't increase compile time, it's performed at run-time, which can affect the user.
      An out-of-bounds error should be caught during testing. Using `at` slows down the user without adding a safety benefit (Because we assume there are no out-of-bounds errors in user software).
      You can use `at` while you learn programming, because you're likely to make mistakes, but I can't recommend using it in production code.

  • Ged

    5. About std::array. We talked about size_type when we want to get the length of the array. We used r-value. But why don't we just use " const (datatype) length = 5(example) ". I wrote the "const" because it doesn't allow me to use length in the std::array without "const". In a situation if we write a lot of code and use a lot of std::array. Manually changing the length number would be very annoying. As well as we wouldn't need to convert size_type. I see a lot of pros in this situation or am I missing something?

    5. I don't understand your suggestion, can you post a full example?

    I'm writing a new post, because for some reason it only allows me to reply through a phone.

    In example number 1 if we use that line a lot in our code and it happens that we need to change the array from 15 to 25 it can take a long time replace 15 in every line. Isn't the second option better?

    Extra question. This came up to me because a lot of the tasks that I'm doing online ask the user to input the length of an array.
    Let's say I have 3 different files with the length of an array and its elements. How do I use std::vector to input all that? Cause usually I always used simple fixed arrays, then after finding out about pointers, I've started using them. But from the lesson with the vector, there weren't any examples of situations where the user needs to input the length.

    • nascardriver

      You can use a type alias that you then use instead of the array type

      Now you only have to update the alias when you want to change the length.

      If you know how many elements your vector will have beforehand, you can use either one of those:

  • Ged

    A few questions to make things a bit more clear for myself.
    1. The only 2 things we should be using when working with arrays are std::vector and std::array, should we forget about pointer arrays and simple fixed arrays? (just know that they exist)?
    2. std::vector is used when we need a dynamical array (we don't know what length it will be).
    3. std::array is used when we need a fixed array (we know its length).
    4. But what if we need to have a 2d or 3d array? If we write it int array[x][y] or int array[x][y][z]. It is the easiest to understand, but I feel it is bad for practice. Should we always go with the flatten (x*y) method as you specified in "6.14 topic" to avoid confusion?

    5. About std::array. We talked about size_type when we want to get the length of the array. We used r-value. But why don't we just use " const (datatype) length = 5(example) ". I wrote the "const" because it doesn't allow me to use length in the std::array without "const". In a situation if we write a lot of code and use a lot of std::array. Manually changing the length number would be very annoying. As well as we wouldn't need to convert size_type. I see a lot of pros in this situation or am I missing something?

    6. Last thing about the last code in this topic.

    There is a special implementation for std::vector of type bool that will compact 8 booleans into a byte!

    How to understand this sentence "8 booleans into a byte". Can the array have a maximum of 255 length or I misunderstood something?

    I do apologise if I asked too many questions, but I don't wanna leave things out that I don't understand. Thank you in advance.

    • nascardriver

      1. This depends on your field of work. Low-level code will probably want to use a custom container for higher efficiency or better memory usage. Unless you have a reason to implement a container yourself, you should stick to those in the container library, which `vector` and `array` are a part of ( ).

      2. Correct.

      3. Correct.

      4. One-dimensional arrays are easier to work with most of the time. If you really want a multidimensional array, you can do that with `std::array` too. Either by using a long type definition or by writing a custom type that creates the array for you.

      5. I don't understand your suggestion, can you post a full example?

      6. Without the specialization, each element of the vector will take up `sizeof(bool)` bytes. That's a lot of wasted space, because a bool is either false or true, so a bool fits into a single bit. 1 byte is 8 bits, so we can store 8 bools in 1 byte, which means we can store 8 times the amount of elements without using any more memory.

Leave a Comment

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