1

I have discovered an interesting problem that I am unsure of the reason. Here is my code:

#include<vector>
#include<iostream>
using namespace std;

std::vector<int>&& fun_1()
{
    std::vector<int> v{ 1, 2, 3 };
    return std::move(v);
}

std::vector<int>&& fun_2()
{
    std::vector<int> v(3, 2);
    return std::move(v);
}

int main() {
    //std::vector<int> v1 = fun_1();
    std::vector<int> v2 = fun_2(); //why isn't move-constructor called? 
    //out << v1.data() << endl;//0x00
    cout << v2.data() << endl;//0x00
}

I have two questions.

Firstly, why are v1.data() and v2.data() both returning a zero pointer? I had expected the move constructor of std::vector<int> to be called, but it seems like it wasn't.

Secondly, when I uncomment the first line in the main function, a memory error is raised when the function exits. It appears to be occurring during the deletion of some object related to v1. I am working in the Visual Studio 2022 environment.

Could someone please explain both issues to me?

8
  • Enable warnings in your compiler. It would have likely told you what the problem is: When you return from fun_2 to which object do you think the returned reference refers? Do you think that this object is still alive when you use the reference to initialize v2? (And the same applies to fun_1/v1.) Commented Sep 25, 2024 at 16:14
  • 6
    In both cases you return dangling reference. Commented Sep 25, 2024 at 16:14
  • Configure compiler to threat warnings as errors and compiler will report a problem: godbolt.org/z/xoh6Gb9br Commented Sep 25, 2024 at 16:17
  • 1
    Side note, even if correct return std::move(v); would not optimize anything. Just return the vector and return value optimization will do the rest. Commented Sep 25, 2024 at 16:20
  • is a moved from vector guaranteed to have a null data ? I didnt find anything like that. After moving from it it is empty, begin == end, but data could be anything afaik Commented Sep 25, 2024 at 16:40

1 Answer 1

6

In both fun_1 and fun_2 you return a dangling reference to a local variable.

Dereferencing it invokes UB (undefined behavior). This means the standard gives no guarantee about the behavior of the program.

Enabling all compiler warnings might help to get an alert about this.

MSVC (latest version) issues:

warning C4172: returning address of local variable or temporary : v

GCC issues:

warning: reference to local variable 'v' returned

clang issues:

warning: reference to stack memory associated with local variable 'v' returned

Live demo

You mentioned that you used Visual Studio 2022. The default compiler that comes with it is MSVC. If you don't get the warnings above your compiler is probably not up-to-date.

A side note:
Returning a std::vector<int>&& here will not give you any benefit anyway.
Simply return std::vector<int> by value.
The compiler should either employ return value optimization (NRVO) to avoid the copy altogether, or at least the vector will be moved out the function and into the assigned variable in main.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.