Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ returning an rvalue doesn't work and segfault

I have a function what creates a vector, does somthing with it and then return it as an rvalue using std::move.
When I am assigning it to a variable, I’m expecting to call std::vector‘s move constructor std::vector::vector(vector&&).
But I’m getting a segmentation fault.

Here’s my code:

#include <iostream>
#include <vector>

std::vector<int>&& getVector(int start)
{
    auto result = std::vector<int>();
    result.reserve(10);
    for (int i = start; i < start + 10; i++)
        result.push_back(i);
    return std::move(result);
}

int main()
{
    std::cout << "Did I break here 1" << std::endl;
    auto vec = getVector(10);
    std::cout << "Did I break here 2" << std::endl;
}

It gives me

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Did I break here 1
[1]    55419 segmentation fault <executable_file>

I just guessing there’s someting wrong with the move constructor or the rvalues. Btw I return an rvalue to not copy the vector’s value an steal the pointer to it.

>Solution :

You are returning a reference to the local variable result. That object is destroyed before the function returns and you are then trying to move-construct vec from a dangling reference.

You do not need to return-by-rvalue-reference or to std::move explicitly in a return statement to get move semantics. You should just do the straight-forward thing:

std::vector<int> getVector(int start)
{
    auto result = std::vector<int>();
    //...
    return result;
}

//...

auto vec = getVector(10);

Now vec will be move-constructed from result and the constructor call may even be elided. Before C++17 there may be three (including = std::vector<int>()) move constructor calls if the compiler is not optimizing. Since C++17 there will only be one at most. In any case there will not be any copy constructor calls.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading