Returning address of local variable

P

Prasoon

#include<stdio.h>

int* func()
{

int i=2;
return &i;
}

int main(void)
{

int *p;
p=func();
int x=*p;
printf("%d",x);
}

According to me the above code should not work as func returns address
of a local variable which gets destroyed after the function func is
exited!!!!

Am I correct??/

But why am I getting 2 as the output if I am correct??
Any fault with my compiler???/
 
W

Wolfgang Draxinger

Prasoon said:
#include<stdio.h>

int* func()
{

int i=2;
return &i;
}

int main(void)
{

int *p;
p=func();
int x=*p;
printf("%d",x);
}

According to me the above code should not work as func returns address
of a local variable which gets destroyed

It doesn't get destroyed. It get's out of scope, totally different concept.
Getting out of scope doesn't mean, that the content of the memory addressed
by "&i" in the scope of "func" will be overwritten. Most likely it will be
there, until it get's overwritten due to use of the same memory space by
another object.
after the function func is
exited!!!!

Am I correct??/

So far and in a coarse sense yes.
But why am I getting 2 as the output if I am correct??

Because you're invoking undefined bahaviouer. Depending on system and
compiler anything may happen between getting the data out which was stored
there lastly and your computer becoming sentient make him chasing you down
the street.
Any fault with my compiler???/

Nope. Just undefined bahaviour. The compiler, if he was a crank, could as
well have implemented an easter egg on it and were still within the bounds
of the C standard.


Wolfgang
 
P

Prasoon

It doesn't get destroyed. It get's out of scope, totally different concept.
Getting out of scope doesn't mean, that the content of the memory addressed
by "&i" in the scope of "func" will be overwritten. Most likely it will be
there, until it get's overwritten due to use of the same memory space by
another object.



So far and in a coarse sense yes.


Because you're invoking undefined bahaviouer. Depending on system and
compiler anything may happen between getting the data out which was stored
there lastly and your computer becoming sentient make him chasing you down
the street.


Nope. Just undefined bahaviour. The compiler, if he was a crank, could as
well have implemented an easter egg on it and were still within the bounds
of the C standard.

Wolfgang

will declaring the variable i as static will make the code free from
invoking UB???
I think yes....
 
E

Eric Sosman

Wolfgang said:
It doesn't get destroyed. It get's out of scope, totally different concept.

It *does* get "destroyed," in the sense that its lifetime
comes to an end (6.2.4p2,p4).

Scope and storage duration are, indeed, different concepts.
It is possible for a perfectly good variable to be out of scope
during its lifetime: for example, `x' in the given code is out
of scope while printf() is executing even though `x' still exists.
 
S

Stephen Sprunk

Prasoon said:
#include<stdio.h>

int* func()
{

int i=2;
return &i;
}

int main(void)
{

int *p;
p=func();
int x=*p;
printf("%d",x);
}

According to me the above code should not work as func returns address
of a local variable which gets destroyed after the function func is
exited!!!!

Am I correct??/

But why am I getting 2 as the output if I am correct??
Any fault with my compiler???/

You are invoking Undefined Behavior. A crash or "wrong" result is not
guaranteed; the result is completely undefined.

One possible result of UB is that everything continues to "work" as you
had hoped, but that isn't required to be consistent, either, and many
such cases that "work" mysteriously stop "working" at the moment when
you have to demonstrate the code for your boss/teacher/customer or when
you change some other, completely unrelated, part of the program.

S
 
G

gaurav

     It *does* get "destroyed," in the sense that its lifetime
comes to an end (6.2.4p2,p4).

     Scope and storage duration are, indeed, different concepts.


The lifetime of a variable is how long it lives. A variable stops
"living" when it goes out of scope and is no longer accessable. A
variable's scope is the block in which it is contained.
Correct????

It is possible for a perfectly good variable to be out of scope
during its lifetime:

Are u talking about static variables????
for example, `x' in the given code is out
of scope while printf() is executing even though `x' still exists.

Not getting you!!!!
 
G

gaurav

The same problem with this too...right????
char *Blah()
{
char strDing[20] = "hello bob!";
return strDing;
}

But if I change the above code to

char *Blah()
{
char *strDing = "hello bob!";/*String Literal*/
return strDing;
}

Will that make any difference or not ????
 
B

Beej Jorgensen

gaurav said:
The lifetime of a variable is how long it lives. A variable stops
"living" when it goes out of scope and is no longer accessable.

Here's an example of a variable "a" going out of scope when bar() is
called, but "a" still exists:

void bar(void)
{
int b;

b = 10; // in scope
a = 40; // ERROR out of scope, but "a" still exists in main
}

int main(void)
{
int a;

a = 10; // in scope

bar();

a = 20; // in scope, and still alive

return 0;
}

-Beej
 
B

BartC

Beej Jorgensen said:
Here's an example of a variable "a" going out of scope when bar() is
called, but "a" still exists:

void bar(void)
{
int b;
b = 10; // in scope
a = 40; // ERROR out of scope, but "a" still exists in main
}

int main(void)
{
int a;
a = 10; // in scope
bar();
a = 20; // in scope, and still alive
return 0;
}

a in main (main::a or main.a) is in scope but not visible during the call to
bar(). (I think it depends on whether you mean lexical or dynamic scope.)
 
E

Eric Sosman

gaurav said:
The lifetime of a variable is how long it lives. A variable stops
"living" when it goes out of scope and is no longer accessable. A
variable's scope is the block in which it is contained.
Correct????

First sentence correct, second incorrect, third correct
(pretty much).

"Scope" is a property of identifiers, not of variables
as such: An identifier can designate a variable, or a function,
or a macro, or an enum constant, or various other things in a C
program. The program can use the same identifier to refer to
different things at different places -- in different "scopes."
For example, `x' can be one function's first parameter, can
refer to an auto variable in some other function, can be the
name of a struct element somewhere else, and so on. The scope
of each of these uses is the region of program source in which
`x' has the same meaning. Silly example:

int f(void) {
int x = rand() - RAND_MAX / 2;
return x < 0 ? g(x) : h(x);
}

int g(int z) {
return z + 42;
}

int h(int a) {
x:
--a;
if (a % 2 == 0) goto x;
return a;
}

This example uses the identifier `x' to mean two different
things in two different scopes: It is an auto variable in
the function f(), and it is a label in the function h().
`x' has no meaning at all in function g().

Now: When the execution of f() gets as far as the
declaration, an auto variable comes into existence and remains
in existence until f() returns. Within the scope of f(),
the identifier `x' refers to that variable. But what if f()
calls g()? Inside g(), `x' means nothing; the identifier is
not in scope, even though the variable it once named still
exists (because f() hasn't returned yet). Or what if f()
calls h()? Inside h(), `x' is a statement label and does
not refer to a variable at all -- yet f() still has not
returned and its auto variable still exists.

Scope is a lexical property; lifetime is a dynamic property.
 
E

Eric Sosman

BartC said:
[...]
a in main (main::a or main.a) is in scope but not visible during the
call to bar(). (I think it depends on whether you mean lexical or
dynamic scope.)

The phrases "lexical scope" and "dynamic scope" appear
nowhere in the Standard. I think that if you want to use the
word "scope" with a meaning different from the Standard's (see
section 6.2.1), it is incumbent on you to warn readers that you
are making up your own nomenclature. Better still would be to
avoid confusion by using a completely different term; I believe
"Haddocks' Eyes" is available at the moment.
 
K

Kenny McCormack

Eric Sosman said:
BartC said:
[...]
a in main (main::a or main.a) is in scope but not visible during the
call to bar(). (I think it depends on whether you mean lexical or
dynamic scope.)

The phrases "lexical scope" and "dynamic scope" appear
nowhere in the Standard. I think that if you want to use the
word "scope" with a meaning different from the Standard's (see
section 6.2.1), it is incumbent on you to warn readers that you
are making up your own nomenclature. Better still would be to
avoid confusion by using a completely different term; I believe
"Haddocks' Eyes" is available at the moment.

Words fail me. You must be a real hit with the girls.
 
K

karthikbalaguru

#include<stdio.h>

int* func()
{

int i=2;
return &i;

}

int main(void)
{

int *p;
p=func();
int x=*p;
printf("%d",x);
}

According to me the above code should not work as func returns address
of a local variable which gets destroyed after the function func is
exited!!!!

Am I correct??/

But why am I getting 2 as the output if I am correct??
Any fault with my compiler???/

It is 'Undefined Behaviour' - It can either give corrupt output or
correct
output.

Karthik Balaguru
 
R

Richard Bos

gaurav said:
The same problem with this too...right????
char *Blah()
{
char strDing[20] = "hello bob!";
return strDing;
}
Yes.

But if I change the above code to

char *Blah()
{
char *strDing = "hello bob!";/*String Literal*/
return strDing;
}

Will that make any difference or not ????

Yes, but beware. It is now a string literal, and that means that you
can't change its contents. (Well, you can try, but it causes undefined
behaviour.)

Generally, when you return something from a function, you want to return
either a value, a pointer to an object you got from malloc() et al.
(either inside the function itself, or earlier in the program, and
stored in, say, a linked list), or a pointer to something the function
got from its caller as a parameter. There are exceptions, but they're
much less common than those three.

Richard
 
G

Giacomo Degli Esposti

The same problem with this too...right????
char *Blah()
{
char strDing[20] = "hello bob!";
return strDing;

}

Yes. The return statement is equivalent to this:
return &strDing[0]

So you are returning the address of a local variable.
But if I change the above code to

char *Blah()
{
  char *strDing = "hello bob!";/*String Literal*/
  return strDing;

}

Will that make any difference or not ????

Yes again. In this case you are not returning the address of a
local variable [1] you are returning a pointer to a string
constant, which is in a different storage and is not
destroyed when the function returns.

ciao
Giacomo

[1] if you returned &strDing then you would return the address
of a local variable, but in this case it would also be of
different type: char ** in stead of char * so
the compiler would probably emit a warning
 
J

jameskuyper

karthikbalaguru said:
It is 'Undefined Behaviour' - It can either give corrupt output or
correct
output.

More accurately, one of the infinitely many kinds of correct behavior
for such a program is to produce garbage output, another is to do
exactly what the author might otherwise expect it to do, despite the
fact that the standard gives no legitimate excuse for having any
expectations whatsoever about how the program will behave.
 
W

Willem

jameskuyper wrote:
) More accurately, one of the infinitely many kinds of correct behavior
) for such a program is to produce garbage output, another is to do
) exactly what the author might otherwise expect it to do, despite the
) fact that the standard gives no legitimate excuse for having any
) expectations whatsoever about how the program will behave.

Even worse, for a lot of forms of UB, it is actually quite likely
that the program will first do exactly what the author expects it to
(especially when unit-testing or in other test conditions), and only to
do something else in some edge cases or under production load or whatever.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
L

lawrence.jones

gaurav said:
But if I change the above code to

char *Blah()
{
char *strDing = "hello bob!";/*String Literal*/
return strDing;
}

Will that make any difference or not ????

Yes, it makes a difference. In that case, you're returning the address of
a string literal, not an auto variable. String literals have static
storage duration and thus exist for the entire life of the program.
 
R

Richard Bos

Willem said:
jameskuyper wrote:
) More accurately, one of the infinitely many kinds of correct behavior
) for such a program is to produce garbage output, another is to do
) exactly what the author might otherwise expect it to do, despite the
) fact that the standard gives no legitimate excuse for having any
) expectations whatsoever about how the program will behave.

Even worse, for a lot of forms of UB, it is actually quite likely
that the program will first do exactly what the author expects it to
(especially when unit-testing or in other test conditions), and only to
do something else in some edge cases or under production load or whatever.

And by preference, it will work fine while you hack on it, but crash
spectacularly and unpleasantly when your team mangler tests the thing.

Never forget that computers are malicious creatures, out to get you.

Richard
 
B

BartC

Eric Sosman said:
BartC said:
[...]
(I think it depends on whether you mean lexical or dynamic scope.)

The phrases "lexical scope" and "dynamic scope" appear
nowhere in the Standard.

The behaviour being discussed is not unique to C, so it seemed acceptable to
use more informal terms, especially as we aren't in comp.std.c.
I think that if you want to use the
word "scope" with a meaning different from the Standard's (see
section 6.2.1), it is incumbent on you to warn readers that you
are making up your own nomenclature.

I'm guessing most people reading this group aren't intimately acquainted
with Concepts VI:2:1.

I've just realised I'm working on a language where it is possible to access
main.a (and so on) from anywhere else. Now I have to work out (1) how to
implement it and (2) what it actually means (bearing in mind there might be
multiple main.a's in existence).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top