-6

My questions are marked in code comments in the snippet below.

int *foo(){
    int a = 10;
    int b = 20;
    return &b;
}
int *foo2(){
    int aa = 44;
    int bb = 40;
    return &bb;
}

int main(int argc, char* argv[])
{
    int *p = foo();
    int *p2 = foo2();

    int  a = 700;
    int *b = & a;

//  cout<<*b<<endl; /* what & why the difference from adding & removing this line?? */
    cout<<a<<endl;
    cout<<*p<<endl; /* what & why happened to "p" */

    return 0;
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Rocky
  • 1,287
  • 3
  • 15
  • 37

2 Answers2

5

In foo() and foo2() you are returning pointers to local variables. These locals have automatic storage and it is undefined behavior to use a pointer to them once they go out of scope. Therefor p and p2 contain nothing useful. It might work, it might not.

I can't understand your question very well, so I hope I got it all.

Cory Nelson
  • 29,236
  • 5
  • 72
  • 110
  • 2
    +1 for bravery. (And for "automatic storage") – Lightness Races in Orbit Jul 25 '11 at 02:36
  • @Nelson thanks for your patience. I just wanna know more detail about the "undefined behavior". – Rocky Jul 25 '11 at 02:38
  • @Zhao: **Undefined behaviour** results when programs attempt to do things for which the standard defines no semantics, and requires no diagnostic either. Examples include dereferencing invalid pointers and dividing by zero. Executing such programs may cause them to produce incorrect results, crash, silently "work", or even format the hard drive. **Avoid like the plague.** – Lightness Races in Orbit Jul 25 '11 at 02:40
  • "Undefined behavior" means that C++ doesn't define what the result of your code is. It might crash. It might print the great question of life, the universe, and everything. If it does work, it will work only by chance. – Cory Nelson Jul 25 '11 at 02:43
  • @Tomalak thank you,I got it.If I remove the line:cout< – Rocky Jul 25 '11 at 02:44
  • @Zhao Rocky: No, the pointer `p` will not return the value of `bb` because `bb` doesn't exist anymore. It went away when the function `foo2()` returned. So `p` will not be valid. *Anything* can happen if you attempt to dereference an invalid pointer. – In silico Jul 25 '11 at 02:45
  • @Zhao: No. `bb` no longer exists, and `a` has _nothing to do with it_. Read the answers you have been given, and also find yourself [a decent C++ book](http://jcatki.no-ip.org/fncpp/Resources). – Lightness Races in Orbit Jul 25 '11 at 02:45
  • @In silico So the console outputs "40" just by chance,and is not right,yes?(I just mean the result,not the code) – Rocky Jul 25 '11 at 02:49
  • @Zhao Rocky: Yes, the reason why you still get `40` is because nothing has overwritten the memory location for the variable `40`. But you should never write code that depends on that kind of knowledge. This `cout<<*p< – In silico Jul 25 '11 at 02:49
  • @Zhao Yes, completely by chance. The code is not right. – Cory Nelson Jul 25 '11 at 02:50
  • @In Silico: :) Thanks! I just confused about why the console always printed "40",now I see,"always" sometimes means "by chance".:) – Rocky Jul 25 '11 at 02:53
  • @Zhao Rocky: I'm glad we were able to clear things up, but please pick up [a good introductory C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list) where these kinds of things are covered and much more because your question demonstrates that you have a fundamental misunderstanding of how C++ works. – In silico Jul 25 '11 at 02:55
  • Yeah,And thank you all for your patience and good answers and I have to apologize for my Bad Question. – Rocky Jul 25 '11 at 03:02
1

Before I attempt to answer the questions in the comments of your code snippet, let's step through this:

int *foo(){
    int a = 10;
    int b = 20;
    return &b;
}
int *foo2(){
    int aa = 44;
    int bb = 40;
    return &bb;
}

int main(int argc, char* argv[])
{
    int *p = foo();
    int *p2 = foo2();

In both foo() and foo2(), you're returning a pointer to something located in the function call stack (that is, a, b, aa, and bb), which will go away when the function returns. Within the function a pointer to variables a or b in foo() or a pointer to variables aa or bb in foo2() will point to something valid.

But when the function returns, those variables will cease to exist. So in both of these functions the returned pointer will not be valid, and consequently p and p2 will be invalid as well.

    int  a = 700;
    int *b = &a;

You're assigning the address of the variable a to pointer b.

//  cout<<*b<<endl; /* what & why the difference from adding & removing this line?? */

Adding the line will dereference b and print out the value of the pointee (in this case, the value of variable a which is 700).

    cout<<*p<<endl; /* what & why happened to "p" */

Since p is invalid as explained earlier, it will invoke undefined behavior, meaning anything can happen. That can include it working just fine (which I doubt), printing garbage values, crash outright, or explode your computer. Just don't try to dereference an invalid pointer.

In silico
  • 51,091
  • 10
  • 150
  • 143