Re: why I got this answer?

90 views
Skip to first unread message

Jasen Betts

unread,
Mar 11, 2013, 7:25:47 PM3/11/13
to
On 2013-02-26, 谢成骏 <bbb...@gmail.com> wrote:
> Hi all.
> I write a small program. But I can't understand the result of it. here is my code:
> -----------------------------------------
> #include <stdio.h>
>
> int* foo(int n)
> {
> int *p = &n;
> return p;
> }

n 'evaporates' after you hit the return
the value returned in p points to where n used to be.

> output:
> [999]
> [999]
> Why *p is 999?

999 got put where n used to be.

--
⚂⚃ 100% natural
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

Barry Schwarz

unread,
Mar 11, 2013, 7:25:40 PM3/11/13
to
On Tue, 26 Feb 2013 10:51:39 -0600 (CST), ??? <bbb...@gmail.com>
wrote:

>Hi all.
> I write a small program. But I can't understand the result of it. here is my code:
>-----------------------------------------
>#include <stdio.h>
>
>int* foo(int n)

n is a variable which exists only while foo is executing.

>{
> int *p = &n;

p points to n.

> return p;

The value in p is returned to the calling function. foo terminates
and all of its local variables cease to exist, particularly n. Since
n longer exists, the value that was returned to the calling function
becomes, by definition, indeterminant..

>}
>
>int f(int m)
>{
> int n = 1;
> return 999;
>}
>
>int main(int argc, char *argv[])
>{
> int num = 1;
> int *p = foo(num);

As explained above, the value returned by foo is indeterminant.

> int q = f(999);
> printf("[%d]\n[%d]\n", *p, q);

Here you dereference p. Since its value is indeterminant, this
invokes undefined behavior.

>}
>-----------------------------------------
>output:
>[999]
>[999]
>Why *p is 999?

With undefined behavior, any response is possible and all responses
are equaly correct and incorrect..

As a practical matter, let us assume that local variables are placed
on the stack that starts at 0x1000.
1 - In main, num is created at 0x1000 and initialized to 1.
2 - In main, p is created at 0x1004 and foo is called.
3 - In foo, n is created at 0x1008 and set to 1.
4 - In foo, p is created at 0x100c and initialized to 0x1008.
5 - foo returns 0x1008 (which is stored in p at 0x1004), its
variables are destroyed, and the stack pointer is reset to 0x1008.
6 - In main, q is created at 0x1008 and f is called.
7 - In f, m is created at 0x100c and set to 999.
8 - In f, n is created at 0x1010 and set to 1.
9 - f returns 999 (which is stored in q at 0x1008), its variables
are destroyed, and the stack pointer is rest to 0x100c.
10 - In main, p contains 0x1008 and that address is dereferenced to
produce an int. Since 0x1008 happens to be the address of q, *p
evaluates to 999.

>Then I changed my code:
>-----------------------------------------
>#include <stdio.h>
>
>int* foo(int n)
>{
> int *p = &n;
> return p;
>}
>
>int f()
>{
> int n = 1;
> return 999;
>}
>
>int main(int argc, char *argv[])
>{
> int num = 1;
> int *p = foo(num);
> int q = f();
> printf("[%d]\n[%d]\n", *p, q);
>}
>------------------------------------
>output:
>[1]
>[999]
>Why *p is 1? I can't understand why.

You should rerun your tests with all optimizations turned off.

--
Remove del for email

Thomas Richter

unread,
Mar 11, 2013, 7:25:44 PM3/11/13
to
Am 26.02.2013 17:51, schrieb 谢成骏:
> Hi all.
> I write a small program. But I can't understand the result of it. here is my code:
> -----------------------------------------
> #include<stdio.h>
>
> int* foo(int n)
> {
> int *p =&n;
> return p;

Here you take the address of the formal parameter "n", but this argument
goes out of scope as soon as the function returns, so the result is
undefined.



> }
>
> int f(int m)
> {
> int n = 1;

This "n" has also local scope, and in particular is distinct from the
formal parameter of "foo". As this initialization does not cause any
effect, the compiler can even remove it (and might do so when
optimization is enabled).

> return 999;
> }
>
> int main(int argc, char *argv[])
> {
> int num = 1;
> int *p = foo(num);
> int q = f(999);
> printf("[%d]\n[%d]\n", *p, q);
> }
> -----------------------------------------
> output:
> [999]
> [999]
> Why *p is 999?

It could also be any other value.

> Then I changed my code:
> -----------------------------------------
> #include<stdio.h>
>
> int* foo(int n)
> {
> int *p =&n;

Same problem.

> return p;
> }
>
> int f()
> {
> int n = 1;

Again, a statement without observable effects.

> return 999;
> }
>
> int main(int argc, char *argv[])
> {
> int num = 1;
> int *p = foo(num);
> int q = f();
> printf("[%d]\n[%d]\n", *p, q);
> }
> ------------------------------------
> output:
> [1]
> [999]
> Why *p is 1? I can't understand why.

Same as above. *p could be anything. Actually, it would not even
surprise me if the code would crash if you would assign to *p.

Greetings,
Thomas
Reply all
Reply to author
Forward
0 new messages