Okd
Okd

Reputation: 197

Memory location of a const reference

I have the following C++ code, and I'm running g++ (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0:

#include <iostream>

const int& getConst() {
  int x = 10;
  printf("x ptr: %p\n", &x);
  const int &y = 10;
  printf("y ptr: %p\n", &y);
  return y;
}

int main() {
  int start = 0;
  printf("start ptr: %p\n", &start);
  const int &t = getConst();
  printf("t: %d\n", t);
  printf("t ptr: %p\n", &t);
  int end = 0;
  printf("end ptr: %p\n", &end);
  return 0;
}

And the output of this code is as follows:

root@78600f6683dd:/home/test/question# ./a.out
start ptr: 0x7ffdcd2381f8
x ptr: 0x7ffdcd2381c8
y ptr: 0x7ffdcd2381cc
t: 10
t ptr: 0x7ffdcd2381cc
end ptr: 0x7ffdcd2381fc

There are two things I'm confused about the result:

  1. The memory location of start and end within the function main() are 0x7ffdcd2381f8 and 0x7ffdcd2381fc respectively. The memory locations of variables of main function are ascending. The main function calls getConst() function, but the location of variables within the function getConst() are 0x7ffdcd2381c8 and 0x7ffdcd2381cc, which are both descending comparing to variables within the main() function. Since main functions calls getConst() function, shouldn't location of getConst() be on top of the stack to main()?

  2. Within getConst() function, y is a const reference to 10. As far as I understand it, the procedure is that, a temporary int variable is created with a value of 10, and y references to it. As seen in the output of the program, both y and t point to the same memory location. However the temporary variable is a variable defined in stack, shouldn't it be cleaned up after getConst() function returns? If so, how can t still get the correct value?

Upvotes: 0

Views: 613

Answers (1)

Alan Birtles
Alan Birtles

Reputation: 36399

Your code has undefined behaviour as it is returning a reference to a temporary variable so anything could happen.

However what is actually happening is probably that the returned reference is basically a pointer, the memory pointed to is no longer valid but the pointer itself is just a number so it is unsurprising that you are able to print its value. Printing the value of the reference will probably work as the runtime doesn't "clean up" deallocated stack memory, that would be a waste of time, when the memory is re-used it will be re-initialised. If you call a new function containing uninitialised variables it wouldn't be surprising if they also have the same values as set in getConst. This of course is all undefined behaviour.

Traditionally heap memory grew up from the bottom of the memory and stack grew down from the top, when the two met your program was out of memory. With modern virtual memory schemes this isn't literally the case any more but the stack is still generally a fixed size block of memory which is used from the end back to the front so it is not unusual for new stack allocations to have lower addresses than old ones. This is what makes overflowing stack variables so dangerous, you aren't overwriting unused memory you are actually overwriting variables earlier in the stack.

Upvotes: 2

Related Questions