0

Possible Duplicate:
Can a local variable's memory be accessed outside its scope?

I thought the following call to f() will get a pointer to a local memory that will not be handled by the compiler (which is dangerous according to the textbook). However, it still works well. Not sure whether this is safe or not.

#include <iostream>

using namespace std;

int * f()
{
   int  v[1000000];
   for (int i=0; i<1000000; i++) v[i]=i;
   cout<<v[7]<<endl;
  return  v;
}

int main()
{
   int * v = f();
   cout<<v[7]<<endl;
   return 0;
}
Community
  • 1
  • 1
Hailiang Zhang
  • 17,604
  • 23
  • 71
  • 117

5 Answers5

4

The pointer v in main() is a dangling pointer after f() returns. Dereferencing a dangling pointer is undefined behaviour, meaning anything can happen:

  • it could crash
  • it could print an incorrect integer value
  • it could print the correct integer value
hmjd
  • 120,187
  • 20
  • 207
  • 252
4

Because it is Undefined Behavior and an Undefined Behavior does not necessary mean a crash.
It is unsafe ofcourse.
An Undefined Behavior means that all safe bets are off and literally anything might happen, So if it does not crash does not mean it is valid. It is invalid and you should just not do it!

Alok Save
  • 202,538
  • 53
  • 430
  • 533
4

Interesting question. Your code is likely to work (or seem to work) on some platforms and to fail on others.

The reason your code seems to work is that the memory the function f() reserves on the stack is released but not erased when f() returns. Being released, the memory becomes available for other functions to use; but it might not be overwritten until another function actually does use it.

Some others here are correctly pointing out that your code evokes undefined behavior, and technically that is true. However, there is a reason you are getting the particular undefined behavior you are getting, and that is what my answer is about.

On some platforms, including the x86, after f() releases the memory of v[], the first memory to be reused will normally be the memory that used to hold v[999999]. It may be a long time before the memory that holds v[0] gets reused. Hence, the data from v[7] is spuriously still present.

There is at least one more wrinkle. Some implementations, using some settings, may overwrite all released memory immediately with random data, to guard against security risks. (What if v[] held a password, for example? The random data would wipe it safely away.)

thb
  • 13,796
  • 3
  • 40
  • 68
1

Undefined behavior: it can work, or crash, or erase your hard drive, or implode into a black hole, or run off with your wife.

One thing's for sure, though: it will cause you to fail your class.

Matt
  • 10,434
  • 1
  • 36
  • 45
1

As noted in other answers, it's undefined behavior so you cannot depend on it working correctly. It may work ok on some platforms or with some compilers but not others. You are 'getting away with it' mostly because your program is small and simple. The more you elaborate the program, the more likely you'll run into problems.

Art Swri
  • 2,799
  • 3
  • 25
  • 36