Padu Merloti
Padu Merloti

Reputation: 3229

Why returning a std::vector is still making a copy?

I have a class that is going to create a pretty big array of data that I don't want to be copied around. For all considerations, it is immutable (read only) for anybody outside my class.

Here's a concept code that shows how I want to implement it:

class C {
public:
    C();
    std::vector<int> const& get_vector() { return m_vector; }
private:
    std::vector<int> m_vector;
};

C::C()
{
    m_vector.push_back(1);
    m_vector.push_back(2);
}

void DisplayVector(std::vector<int> const& new_v)
{
    for (int i = 0; i<new_v.size(); i++)
        std::cout << new_v[i] << std::endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
    C myobj;
    std::vector<int> v = myobj.get_vector();
    v.push_back(3);

    DisplayVector(v);
}

When I step through this code, I see a given memory address for m_vector and the first element of its array (using the begin iterator).

When I return from get_vector, the vector "v" and its first element have a completely different memory address. v.push_back(3) doesn't have any problem modifying v (since it looks it's a copy)

When I call DisplayVector, then it works as I expected and new_v addresses are the same as main v.

What am I doing wrong?

Upvotes: 1

Views: 84

Answers (2)

Marshall Clow
Marshall Clow

Reputation: 16670

int _tmain(int argc, _TCHAR* argv[])
{
    C myobj;
    std::vector<int> v = myobj.get_vector();

After executing this code, you have two vectors; the instance variable myobj.m_vector and v.

Upvotes: 0

Benjamin Bannier
Benjamin Bannier

Reputation: 58604

You explicitly created a copy with

std::vector<int> v = myobj.get_vector();

which you can modify since vis a plain vector<int>. Here v got copy-constructed.

To instead bind a reference (which has to be const because of get_vector's return type) use

const std::vector<int>& v = myobj.get_vector();

or just

const auto& v = myobj.get_vector();

Upvotes: 5

Related Questions