devillighter
devillighter

Reputation: 43

Why does this work? Returning const references in C++

I am fooling around with C++ and const references and am confused why this code works:

#include <iostream>

class A {
public:
    A() : a_(50) {}
    const int& getA() const { return a_; }
private:
    const int a_;
};

int main(int argc, char* argv[])
{
    A* a = new A();
    const int& var = a->getA();
    std::cout << var << std::endl;
    delete a;
    std::cout << var << std::endl;
}

Result:

50
50

Here are my thoughts:

var stores a reference to a_.
when a is deleted, a_ should also be deleted.
when var is accessed again, it no longer contains a valid reference and a segmentation fault should occur.

Why does this work? I do not believe I make a temporary copy.

Upvotes: 1

Views: 364

Answers (4)

mnemosyn
mnemosyn

Reputation: 46301

This is quite tricky because of the const keyword.

True, you could be reading uninitialized memory in this case. Some thoughts on that:

  1. You're not using debug mode: this is generally not a good idea as long as the code hasn't been tested, but it leaves two options:
    • The release mode memory manager does not overwrite the memory, so you acces the last known address, which still works by chance
    • OR The whole operation is completely optimized away because the compiler knows you didn't change the value and it couldn't change from the outside (though that might not be true due to the limitations of const correctness in C++)
  2. You are in debug mode, but have optimizations activated, so the same argument applies
  3. The contents of _a, since marked const are not heap-allocated nor stack allocated but reside in the DATA section of the application, so the reference might indeed be still valid, not only by chance. [EDIT]: This can only be true for static const variables.

You might consider writing a custom memory manager or research on the debug mode behaviour of your compiler, because this is very, very important. Visual Studio will set variables to 0xCDCDCDCD, for example. You will also find funny values such as 0xDEADC0DE at the end of arrays.

Upvotes: 1

bramp
bramp

Reputation: 9741

When you delete a you are freeing the memory and allowing a latter new to override it. Until then all the variables inside your deleted object are still in memory, but may be overridden at any time.

Upvotes: 2

Arve
Arve

Reputation: 7506

Deleting an object does not clear the memory. The value will still be there until the memory is used for something else. So it may work for a while....

Some C++ implementations have a "debug mode" that sets a particular value to all deleted memory to detect bugs like this.

Upvotes: 3

GManNickG
GManNickG

Reputation: 503883

The moment you deleted a, accessing var became your door into undefined behavior land.

It's "working" by chance. The space where var was one referring to is no longer yours, but you got away with accessing it, this time. It could have resulted in a segmentation fault, returned a number other than 50, or reformatted your hard drive.

Remember, seeming to work is one possible way undefined behavior can manifest itself.

Upvotes: 12

Related Questions