0

i've a code that shouldn't work, but it works. Can you tell me why?

#include <iostream>

void f ( int** a, int b ) ;

int main (void) {

    int ** a ;
    a = new int* () ;  

    f(a,5) ;

    std::cout << **a << std::endl ;

    return 1 ;

}

void f ( int** a, int b ) {

    *a = &b ;

}

I declare a pointer to pointer named a, i allocate a pointer to it and then i pass it to f(). The other f() argument is a constant literal, so it is supposed to haven't static memory allocated in main(), ergo it shouldn't exist after f(). Inside f() i assign the memory direction of the local variable b to the pointer to pointer on main copied by f(), then when main() executes f() all local variables should be deleted and then proceed, so a should point to trash, or nothing, but it doesn't and points to 5,value of already deleted b.

What does realy happen? Why this code works?

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
Gonzo RI
  • 71
  • 1
  • 10
  • It invokes undefined behavior and undefined behavior is undefined. – ouah Aug 08 '13 at 17:34
  • When they say it is an undefined behavior, it means it can work the hell out of you by behaving correctly or sometimes it wont work out. – Uchia Itachi Aug 08 '13 at 17:34
  • It doesn't work; it has undefined behaviour. Memory doesn't necessarily disappear when you destroy the object it contains, so a dangling pointer might (or might not) still see the value that used to be there. You should get a compiler warning, if you enable them. – Mike Seymour Aug 08 '13 at 17:34
  • @MikeSeymour i'm compiling using -Wall -pedantic and the compiler doesn't complain. Which flags should i use. – Gonzo RI Aug 08 '13 at 17:37
  • @GonzoRI: Actually, perhaps you won't get a warning. Most popular compilers will diagnose `return &b;`, but it might be that the assignment to `*a` is beyond the compiler's ability to analyse. – Mike Seymour Aug 08 '13 at 17:41
  • @GonzoRI Please do not tag your C++ question as C. – Pascal Cuoq Aug 08 '13 at 19:53

2 Answers2

3

It seems like it works, but actualy it doesn't.

*a points to address on the stack.

When you print **a, what is acutaly printed is the content of certain address on the stack. (The address that contained 5 when you call the function f).

However, because the stack doesn't change much according to your code, the value 5 is still written on the certain address so the value 5 is printed. If you would call to other function and then print **a you will probably get different value.

barak1412
  • 972
  • 7
  • 17
2

The memory doesn't get overwritten right away in your case. This is undefined behaviour and it may not behave the same all the time. Each compiler may treat it differently, you may see different results on different platforms or even in release vs debug modes.

krsteeve
  • 1,794
  • 4
  • 19
  • 29