Returning An Std::pair, Std::unique_ptr&> From A Function Results In Weirdness
I'm having trouble understanding the (to me intricate) mechanisms executed behind the scenes in the following code example:
#include <utility>
#include <memory>
#include <iostream>
struct A {int a;};
struct B {int b;};
std::pair<std::shared_ptr<A>, std::unique_ptr<B>&> FuncA() {
std::shared_ptr<A> a = std::make_shared<A>();
std::unique_ptr<B> b = std::make_unique<B>();
a->a = 12; b->b = 13;
std::cout << "FuncA a: " << a.get() << std::endl;
std::cout << "FuncA b: " << b.get() << std::endl;
std::cout << "FuncA a.a: " << a->a << std::endl;
std::cout << "FuncA b.b: " << b->b << std::endl;
return {a,b};
}
void FuncC(std::pair<std::shared_ptr<A>, std::unique_ptr<B>&> input) {
std::cout << "FuncC a: " << input.first.get() << std::endl;
std::cout << "FuncC b: " << input.second.get() << std::endl;
std::cout << "FuncC a.a: " << input.first->a << std::endl;
std::cout << "FuncC b.b: " << input.second->b << std::endl;
}
void FuncB() {
auto ret = FuncA();
std::cout << "FuncB a: " << ret.first.get() << std::endl;
std::cout << "FuncB b: " << ret.second.get() << std::endl;
std::cout << "FuncC a.a: " << ret.first->a << std::endl;
std::cout << "FuncC b.b: " << ret.second->b << std::endl;
FuncC(ret);
}
int main(){
FuncB();
}
I've compiled the code with both GCC and Clang which give similar results:
FuncA a: 0xfeaec0
FuncA b: 0xfeaed0
FuncA a.a: 12
FuncA b.b: 13
FuncB a: 0xfeaec0
FuncB b: 0x7ffd1c8e4a00
FuncC a.a: 12
FuncC b.b: 479087264
FuncC a: 0xfeaec0
FuncC b: 0x406100
FuncC a.a: 12
FuncC b.b: 1449378512
As is clearly visible, the address of the std::unique_pointer reference (and of course also its value) are not the same as within FuncA, but the address and value of the std::shared_pointer are unchanged.
What's happening here, and what (if anything) could be done to make the reference-passing correct?
Is some form of copy-constructor being executed on the std::unique_ptr as a result of returning from FuncA?
Answer
std::pair<std::shared_ptr<A>, std::unique_ptr<B>&> FuncA() {
// ...
std::unique_ptr<B> b = std::make_unique<B>();
// ...
return {a,b};
}
A local std::unique_ptr<B>
is created and a reference to it is returned as the second element in the pair. This is a dangling reference and is later accessed, giving the program undefined behaviour.
Related Questions
- → Comparing two large files are taking over four hours
- → Setting JSON node name to variable value
- → Compiling GLUT using Emscripten
- → Evaluate check box from a scanned image in node.js
- → Find an easy web server framework for mobile game
- → my https C++ code doesn't work on some sites (binance)
- → Error while opening pivx wallet on ubuntu
- → Why sending a POST by AJAX is interpreted by the HTTP Server as OPTIONS and sending by CURL is effectively a PUT?
- → Python reading in one line multiple types for a calculator
- → How do I properly pass an argument to a function
- → Accessing Websql database with Qt
- → Using Mysql C API for c++ codes
- → How do I set constants at run-time in a c++ header file, imported through Cython?