If I interpret C++ references correctly, they are like pointers, but with guaranteed data integrity (no NULL, no (int*) 0x12345). But what happens when scope of referenced object is leaved? If there are no magic involved (and probably it is not), referenced object will be destroyed behind my back.
I wrote a piece of code to check this:
#include <iostream> using namespace std; class A { public: A(int k) { _k = k; }; int get() { return _k; }; int _k; }; class B { public: B(A& a) : _a(a) {} void b() { cout << _a.get(); } A& _a; }; B* f() { A a(10); return new B(a); } int main() { f()->b(); }
The _k
instance variable was put in to check stack frame existence.
It surprisingly does not segfault and instead prints '10' correctly, while I suppose that A
is allocated on stack and that stack frame of f()
will be overwritten by at least cout<<
call.
Nothing physical happens. A typical implementation will allocate enough space in the program stack to store all variables at the deepest level of block nesting in the current function. This space is typically allocated in the stack in one shot at the function startup and released back at the function exit.
Calling a destructor The cases when object goes out of scope, The program goes out of the scope of a function. The program ends. The block initializing local variables of object goes out of scope.
A variable declared within a block of code has local scope, and is only accessible by other code within the same block. Once the block within which it is declared is exited, the variable goes out of scope.
In C++ a scope is a static region of program text, and so something "out of scope", taken literally, means physically outside of a region of text. For instance, { int x; } int y; : the declaration of y is out of the scope in which x is visible.
this is undefined behavior and you were simply lucky that the memory for a
hadn't been used for anything else yet. In a more complex scenario you would almost certainly get garbage. On my machine I get random garbage with this code. For me, this is likely because I am using a 64-bit machine which uses a register calling convention. Registers get re-used much more often than main memory (ideally...).
So to answer your question of "what happens". Well in this scenario, the reference is likely little more than a limited pointer with friendlier syntax :-). Under the hood the address of a
is stored. Later the a
object goes out of scope, but the B
object's reference to that a
will not be "auto-magically" updated to reflect this. Hence you have an invalid reference now.
Using this invalid reference will yield just about anything, sometimes crashes, sometimes just bunk data.
EDIT: Thanks to Omnifarious, I've been thinking about this. There is a rule in c++ that basically says that if you have a const reference to a temporary, then the lifetime of the temporary is at least as long as the const reference. Which introduced a new question.
EDIT: Moved to separate question for those interested (const reference to temporary oddity)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With