std::find behavior when std::vector is empty but given an initial size

69 Views Asked by At

According to this post, std::find returns the end iterator when the container is empty. However, when I run this code with gcc (GCC) 11.2.1 20220127 (Red Hat 11.2.1-9)


    #include <vector>
    #include <iostream>
    #include <bits/stdc++.h>

    int getIndex(std::vector<int> v, int K)
    {
        auto it = std::find(v.begin(), v.end(), K);
        int index = -1;
        // If element was found
        if (it != v.end()) {
            index = it - v.begin();
        }

        return index;
    }

    int main()
    {
        std::vector<int> map_rows(10);
        for (int ii = 0; ii<5; ii++)
        {
            auto idx = getIndex(map_rows,ii);
            std::cout<<"ii: "<<ii<<", idx: "<<idx<<std::endl;
        }
        return 0;
    }

I get

ii: 0, idx: 0
ii: 1, idx: -1
ii: 2, idx: -1
ii: 3, idx: -1
ii: 4, idx: -1

This happens because I am initializing the vector with the size I need. However, the vector is empty (or so I thought, since I have not pushed any value into it). When instead I use

std::vector<int> map_rows;

I get

ii: 0, idx: -1
ii: 1, idx: -1
ii: 2, idx: -1
ii: 3, idx: -1
ii: 4, idx: -1

I want to initialize the vector size since it might be large. Does anyone have an explanation?

EDIT:

Looks like the way to go, in my case is use reserve as in this code:

#include <vector>
#include <iostream>
#include <bits/stdc++.h>

int getIndex(std::vector<int> v, int K)
{
    auto it = std::find(v.begin(), v.end(), K);
    int index = -1;
    // If element was found
    if (it != v.end() ){
        index = it - v.begin();
        // std::cout<<"*it: "<<*it<<std::endl;
        // index = std::distance(v.begin(), it);
    }

    return index;
}

int main()
{
    std::vector<int> map_rows;
    map_rows.reserve(10);
    for (int ii = 0; ii<5; ii++)
    {
        std::cout<<"map_rows empty?: "<<map_rows.empty()<<std::endl;
        auto idx = getIndex(map_rows,ii);
        std::cout<<"ii: "<<ii<<", idx: "<<idx<<std::endl;
    }
    return 0;
}

However, this is a kind of odd behavior because to me the size should be zero when std::vector is given an initial size. If someone want to explain/elaborate, I will be very grateful.

1

There are 1 best solutions below

1
Ted Lyngmo On

However, the vector is empty (or so I thought, since I have not pushed any value into it)

You are using this constructor:

constexpr explicit vector( size_type count,
                           const Allocator& alloc = Allocator() );

This "Constructs the container with count default-inserted instances of T" - so the vector will not be empty. It will have exactly 10 default-inserted instances of int.

If you on the other hand use

std::vector<int> map_rows;
map_rows.reserve(10);

it will be empty but will have reserved space for 10 ints which means that you can insert at least 10 elements before the vector needs to allocate a bigger chunk of memory and move all the elements to that memory area.

this is a kind of odd behavior because to me the size should be zero when std::vector is given an initial size.

For most people it would come as a surprise if one created it an initial size of 10 but it was in fact created with a size of 0.