2
void foo(int** ptr) {
    int value = 4;
    *ptr = &value;
//    **ptr = value;
}

int main(void) {
    int value = 7;
    int* ptr = &value;
    foo(&ptr);
    cout << *ptr << endl; // 4
    return 0;
}

My Question is - as the value = 4 is no longer valid/out of scope after returning from foo, why *ptr is showing 4 instead of some garbage value?

Kaidul
  • 15,409
  • 15
  • 81
  • 150
  • 13
    Obligatory link to http://stackoverflow.com/a/6445794/1316346 – Kevin DiTraglia Aug 14 '14 at 18:14
  • 1
    It's still got to show something, and 4 is as valid an option as anything else. – dlf Aug 14 '14 at 18:14
  • 1
    The value at an address will not change until something else changes it. "Only pay for what you use." The next thing that allocates and uses that memory will change it's value, but until then, the value is still `4` – Cory Kramer Aug 14 '14 at 18:15
  • 1
    because the stack isn't modified yet, so you get the same variable, if suppose you run it again, and the value=3 this time, then the output will be 3, but if there's something else on the stack, it'll be the (int) value of that byte(s). – coolharsh55 Aug 14 '14 at 18:17
  • @KevinDiTraglia: That answer just got 10 more votes thanks to your comment up there. – barak manos Aug 14 '14 at 18:22
  • Should probably pay special attention to the comment made by @leebriggs in that link... – barak manos Aug 14 '14 at 18:24
  • 1
    @dlf Technically, it doesn't have to show anything. It can chomp up your hard drive instead. – T.C. Aug 14 '14 at 18:25
  • @T.C. In which case it's showing you its teeth! :D – dlf Aug 14 '14 at 18:29

2 Answers2

6

Formal answer: undefined behavior.

Practical answer: no other operation on the stack has yet to override that value.

barak manos
  • 29,648
  • 10
  • 62
  • 114
3

Because you're returning a pointer to a local variable, this is undefined behavior. This includes "appearing" to work, but it's a terrible idea to rely on it in the general case.

In this specific case, the value is left on the stack, and it appears the generated code fetches *ptr just after the call to foo, and before any other function calls. As such, the value has not been overwritten by any other function calls.

If you were to instead insert a function call between the foo(&ptr) and cout << ... statements, the value would more than likely be garbage.

Drew McGowen
  • 11,471
  • 1
  • 31
  • 57