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?
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
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
.