Start learning free

LESSON 110 OF 667 · ARRAYS I

Insert and Remove at a Position in a C++ Vector

Lesson Read the full explanation

TL ; DR:

insert(v.begin() + i, x) puts x at index i. Use erase(v.begin() + i) to take out the item at index i. The other items move to make room or to close the gap.


vector<string> colors = {"red", "green", "blue"};

colors.insert(colors.begin() + 1, "pink");
// colors is now {"red", "pink", "green", "blue"}

colors.erase(colors.begin());
// colors is now {"pink", "green", "blue"}


Full lesson:

push_back adds an item at the end, and pop_back takes the last one away. To work anywhere else in a vector, you need a position.

v.begin() is the position of the first item. Then v.begin() + i is the position of index i. Both insert and erase take such a position, not a plain index.

insert(pos, x) puts x at that position. The items from there on move one place to the right:

vector<string> pets = {"Rex", "Milo"};

pets.insert(pets.begin(), "Luna");
// pets is now {"Luna", "Rex", "Milo"}

erase(pos) takes out the item at that position. The items after it move one place to the left:

pets.erase(pets.begin() + 1);
// pets is now {"Luna", "Milo"}

Watch the indexes. After an insert or a removal, the items behind that spot have new indexes.

C++ doesn't check the position for you. A position past the end can crash the program.


Your task

pets holds the pets waiting at the vet, in order.

Bella has an appointment, so she goes second, at index 1. Then Milo goes home. Take him out of the line.

The code below prints how many pets wait once Bella is in. At the end, it prints the pets left.

Expected output:

4
Rex Bella Luna
STEP 1 OF 2
    Ctrl + Enter to check

    C++ · ARRAYS I

    Array Insert Remove in C++, explained

    Working anywhere in a vector

    push_back adds an item at the end and pop_back removes the last one. To change the middle or the front of a vector, you need two methods that work on a position: insert and erase.

    A position is not a plain number. v.begin() is the position of index 0, and v.begin() + i is the position of index i. This is why both calls below start from begin().

    insert and erase

    insert(pos, x) puts x at the position. Everything from that position on moves one place to the right. erase(pos) removes the item at the position, and everything after it moves one place to the left.

    vector<string> colors = {"red", "green", "blue"};
    
    colors.insert(colors.begin() + 1, "pink");
    // colors is now {"red", "pink", "green", "blue"}
    
    colors.erase(colors.begin());
    // colors is now {"pink", "green", "blue"}
    

    Printing the vector after each call shows exactly this: red pink green blue after the insert, then pink green blue after the erase.

    The new item takes the index you chose. In the example, "pink" is at index 1, and "green", which was at index 1, is now at index 2. Inserting at v.end() works too, and has the same effect as push_back.

    Common mistakes

    • Passing a number. erase(1) does not mean "erase index 1". The call needs a position, so write erase(v.begin() + 1).
    • Forgetting that indexes shift. After an insert or an erase, every item behind that spot has a new index. If you insert at index 1 and then want the item that used to be at index 1, it is now at index 2.
    • Going past the end. C++ does not check the position. v.begin() + 10 on a vector of three items is not an error you can rely on being reported: the program can crash or misbehave. Keep the index between 0 and v.size() for insert and below v.size() for erase.

    The exercise: the vet's waiting line

    pets starts as Rex, Milo, Luna. Bella has an appointment and goes second, at index 1. Then Milo leaves.

    1. Insert Bella at pets.begin() + 1. Milo and Luna each move one place to the right, so the line is now Rex, Bella, Milo, Luna.
    2. Milo is now at index 2, not index 1, because of the insert. Erase pets.begin() + 2.
    vector<string> pets = {"Rex", "Milo", "Luna"};
    pets.insert(pets.begin() + 1, "Bella");
    cout << pets.size() << endl;
    pets.erase(pets.begin() + 2);
    cout << pets[0] << " " << pets[1] << " " << pets[2] << endl;
    

    The output is:

    4
    Rex Bella Luna
    

    If you erased index 1 in step 2 by habit, Bella would be removed instead of Milo. The order of the two calls matters for the same reason.

    Tracing the line

    When an exercise changes a vector twice, write the vector down after each call. Starting from Rex, Milo, Luna: after the insert it is Rex, Bella, Milo, Luna with four items; after the erase it is Rex, Bella, Luna with three. The size grows by one with each insert and shrinks by one with each erase, which is a quick way to check your work: here the first cout prints 4 because it runs between the two calls.

    The same habit helps with a safe index. Before you erase, ask whether the index is smaller than size(). Before you insert, ask whether it is at most size().

    Key takeaways

    • v.begin() + i is the position of index i.
    • insert(pos, x) shifts the items from pos to the right; erase(pos) shifts the items after pos to the left.
    • Re-count the indexes after every insert or erase.
    • Stay inside the vector: C++ does not check positions for you.
    Keep going with C++500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free