returning address of stack variable

M

Manish Tomar

Hi All,

The following code as per my knowledge should not work:

int* some()
{
int b = 10;
return &b;
}


int main(int argc, char** argv)
{
int* test = NULL;

test = some();
printf("test ; %d\n", *test);
*test = 20;

return 0;
}

as it is returning the address of a variable on stack which should not
be valid once the function returns. However, this code seems to be
working absolutely fine in VC++ 6.0 on x86 processor. Could anyone
please explain what is correct or wrong and why is it working.

Also, in the following statement
char *p = "Hello world";
where is the memory for p allocated? is it on stack, heap or global
area and when is it freed, if so?

Thanks in advance,
Manish
 
I

Ian Collins

Manish said:
Hi All,

The following code as per my knowledge should not work:

int* some()
{
int b = 10;
return &b;
}


int main(int argc, char** argv)
{
int* test = NULL;

test = some();
printf("test ; %d\n", *test);
*test = 20;

return 0;
}

as it is returning the address of a variable on stack which should not
be valid once the function returns. However, this code seems to be
working absolutely fine in VC++ 6.0 on x86 processor. Could anyone
please explain what is correct or wrong and why is it working.
You have undefined behaviour. The value is still valid because nothing
has had a chance to overwrite it. Add a couple more function calls
before the printf and see what happens.
Also, in the following statement
char *p = "Hello world";
where is the memory for p allocated? is it on stack, heap or global
area and when is it freed, if so?
It isn't, "Hello world" is a string literal, look it up in the FAQ.
 
R

Richard Heathfield

Manish Tomar said:
Hi All,

The following code as per my knowledge should not work:

And it doesn't. Unfortunately, "not work" can have a variety of outcomes.
One of those outcomes is "what someone who thinks the code is correct would
expect to happen, up until the cost of it not working exceeds the value of
continuing to hire the person writing the code".

In other words, the code will continue to work until your boss is
demonstrating the program to an important customer, at which point it will
fail in a highly visible and embarrassing way.
 
M

Manish Tomar

In statement printf("Hello world"), the printf function receives the
string literal as char* which means it receives some memory address.
Hence some memory should be used to store this string. Where is it?
 
P

pete

Manish said:
In statement printf("Hello world"), the printf function receives the
string literal as char* which means it receives some memory address.
Hence some memory should be used to store this string. Where is it?

printf("It's at %p\n", (void *)"Hello world");
 
S

Suman

pete said:
printf("It's at %p\n", (void *)"Hello world");

IMHO, the OP was looking for stack/heap as an answer. Which of course
if one of the most commonly occuring questions around here.I remember
having read a rather excellent post by Mr. Paul Hsieh regarding this,
sometime
back.STFW.
 
R

Richard Bos

Suman said:
IMHO, the OP was looking for stack/heap as an answer. Which of course
if one of the most commonly occuring questions around here.

The question misses the point; and any definite answer is likely to be
unreliable.
(FWIW, any string literal has static duration; the most logical place to
put them where they occur normally is neither on the stack nor on what
is inaccurately termed the heap; but this is a function parameter, so
putting _this_ string literal where normal function parameters are
passed is also a viable option; other options are not inconceivable; and
most importantly, any program which cares the slightest _where_ string
literals reside is designed broken.)
I remember having read a rather excellent post by Mr. Paul Hsieh regarding
this, sometime back.

I would be most surprised.

Richard
 
F

Flash Gordon

Manish said:
In statement printf("Hello world"), the printf function receives the
string literal as char* which means it receives some memory address.
Hence some memory should be used to store this string. Where is it?

Where ever the implementation chooses to store it. On a number of the
systems I've dealt with it would be burnt in to an EEPROM, but this is
slightly less likely on a desktop PC.

All you need to know is that the string exists for the lifetime of the
program.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc

Inviato da X-Privat.Org - Registrazione gratuita http://www.x-privat.org/join.php
 
S

Suman

pete said:
Suman wrote: [...]
IMHO, the OP was looking for stack/heap as an answer.

"The stack" and "the heap"
aren't part of the C programming language.

Of course not, which is why I avoided any allusion to them in
my reply. I somehow missed the whole thread, and now that
I have it, I do see that the OP _did_ mention stack/heap etc
in early on.

The problem is your reply is technically sound and correct.
But I have a gut feeling it fails to communicate with the OP.
Whence my lament.
 
W

Walter Roberson

In statement printf("Hello world"), the printf function receives the
string literal as char* which means it receives some memory address.
Hence some memory should be used to store this string. Where is it?

Amongst the possible answers, the choice of which will depend upon
the OS, the processor, memory hardware, and the compiler flags:

- ROM
- EEPROM
- discrete memory "buffers"
- hardware synthesized without anything recognizable as "storage"
- punched cards
- "core" memory
- punch tape
- magnetic tape
- mercury acoustic delay line memory
(http://en.wikipedia.org/wiki/Mercury_delay_line)
- "bubble memory"
- laser disc swapped into memory at need
- CD-ROM swapped into memory at need
- memory-mapped magnetic harddrive
- memory marked by the memory controller as "read only"
- FPGAs
- embedded in the generated executable code
- from a memory-mapped copy of the executable, swapped in at need
- created by the code "on the fly" and stored on the stack or heap or
some other convenient location
- microcoded into the processor (yes, seriously -- for example, the
empty string is easy to microcode)
- 2D and 3D holograms

This list is not meant to be exhaustive!
 
K

Keith Thompson

The question misses the point; and any definite answer is likely to be
unreliable.
(FWIW, any string literal has static duration; the most logical place to
put them where they occur normally is neither on the stack nor on what
is inaccurately termed the heap; but this is a function parameter, so
putting _this_ string literal where normal function parameters are
passed is also a viable option; other options are not inconceivable; and
most importantly, any program which cares the slightest _where_ string
literals reside is designed broken.)
[...]

Actually, the fact that the address of the string literal is passed as
an argument to a function *doesn't* mean that the compiler can store
the string literal itself where normal function parameters are stored.
The function could save the address in a statically allocated
variable, and other functions could examine it after the original
function has completed. If that address no longer points to a string
with the value "Hello world", you have a non-conforming
implementation.

If the compiler happens to know that this specific function doesn't do
that (as it might legitimately assume for printf()), it can do
something like this. I seriously doubt that it would be worth the
effort. After all, the string would have to be copied from somewhere
into the parameter; it's simpler to just pass the address of wherever
it is originally.
 
S

Stephen Sprunk

Manish Tomar said:
Hi All,

The following code as per my knowledge should not work:

int* some()
{
int b = 10;
return &b;
}

This invokes undefined behavior. After this, your program can do anything
it wants to, including (but not limited to) exactly what you expect it to
do. It could also do the opposite, but Murphy's Law says that won't happen
until the worst possible moment, i.e. when demoing your product to a
critical customer.

Please note that C doesn't define a "stack"; that's an implementation detail
(though a common way of handling automatic variables).

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Aaron Sorkin


*** ***
 
W

websnarf

Suman said:
IMHO, the OP was looking for stack/heap as an answer. Which of course
if one of the most commonly occuring questions around here.I remember
having read a rather excellent post by Mr. Paul Hsieh regarding this,
sometime
back.STFW.

Oooh! A groupie! :) You may be referring to this post:

http://groups.google.com/group/comp.lang.c/msg/fc53d96db7dad45c

But in general, an inline string, (or "string literal") has implicit
static storage (in some section of memory similar to other statics,
except that you cannot write to it) unless it is used as an
initiailizer to a variable with its own declared storage. In this case
there is no declaration, so you can treat it as if it were some static
object.

(And BTW, its neither on the stack or the heap.)
 
W

websnarf

pete said:
"The stack" and "the heap"
aren't part of the C programming language.

This is probably true in exactly the same way that Keith thinks that
variables are not part of the C programming language (i.e., not at all
except that maybe you can't grep for it in the standard.)

Both, of course, are extremely well defined concepts and referring to
them directly is valuable and important in the ordinary discourse of
programming, especially in the C language.

Perhaps you are confused because there is both a call stack, and an
auto-stack, which may or may not be intertwined depending on the
implementation (though even this detail is technically irrelevant since
the two stacks are synchronized), and the fact that one prominant
implementation has a hardware stack called "the stack" (leading you to
the false dichotomy of "since an implementation refers to it, it must
not be meaningful in the language of the standard"). But the fact is,
function calls and their corresponding returns behave exactly with
stack-like semantics (even longjmp really does nothing more than
mutiple pops at once.) This analogy isn't far fetched -- its
stack-like semantics is what helps you understand how it works.

I have no idea what your problem with the heap is. The fact is that
heap allocations are distinct and independent from the stack and
static/global storage. (In particular, the lifetime of a heap
allocation is dictated arbitrarily by runtime program semantics.) But
this is obvious -- so I don't know what you problem is.
 
S

Suman

Suman wrote: [ ...]
I remember
having read a rather excellent post by Mr. Paul Hsieh regarding this,
sometime
back.STFW.

Oooh! A groupie! :) You may be referring to this post:

http://groups.google.com/group/comp.lang.c/msg/fc53d96db7dad45c

This is the one I had in my mind though :)
<url:
http://groups.google.com/group/comp.lang.c/msg/92bfb8bef9cad3f1 >

I thought this was more in tune with the spirit of the OP's question.

Thanks all the same for coming to aid of my sieve like memory!
 
P

pete

This is probably true in exactly the same way that Keith thinks that
variables are not part of the C programming language (i.e., not at all
except that maybe you can't grep for it in the standard.)

Inapt analogy: You can grep on "variables" in the standard.
Both, of course, are extremely well defined concepts

So is my keyboard. I use a Lexmark Model M. It's the best!
and referring to
them directly is valuable and important in the ordinary discourse of
programming,

Try
especially in the C language.

You do not ever need to have heard of the "stack and the heap"
to write a conforming C program.
 
R

Richard Heathfield

pete said:
Inapt analogy: You can grep on "variables" in the standard.

You won't get any hits, though. Well, I didn't, in the C89 draft. Searching
for the singular, "variable", gave me 23 hits, most of which were to do
with variable argument lists. But I did find these:

"the ``integral promotions'' require that the abstract machine promote
the value of each variable to int size and then add the two int s and
truncate the sum." (referring to a couple of char objects) - 2.1,
non-normative example

"Therefore, for full portability the variable c should be declared as int."
- 3.3.16.1, non-normative example

"The following pair of declarations demonstrates the difference
between a ``variable pointer to a constant value'' and a ``constant
pointer to a variable value.''" - 3.5.4.1, non-normative example

"...assigning a value to a static storage duration variable of type volatile
sig_atomic_t" - 4.7.1.1 - normative text.

"an enumeration variable that has the same type" - A.5, non-normative
appendix

I think the normative text of 4.7.1.1 shows that "variable" is indeed a C
concept. It's a shame, in a way, since it's such a woolly term. Did this
usage in 4.7.1.1 survive into the final C89 standard?
 
C

CoL

Here p has not allocated any memory rather points a chunk of memory
which by ANSI C standard is "Constant static character literal".
When you define char *p = "Hello world";
"Hello world" follows the above mentioned rule.
Now since its static in nature so should be a part of "data Section,
rather than Stack Or Heap.So you can very much return its address from
a fuction as its static by nature.
E.g had it been
char buff[20]="Hello world"; then you cant return its address from
fuction since now its a part of stack local to the function.
I hope you find this helpful.

Regards,
COL
 
P

pete

Richard said:
pete said:


You won't get any hits, though.
Well, I didn't, in the C89 draft. Searching
for the singular, "variable", gave me 23 hits,
most of which were to do
with variable argument lists. But I did find these:

"the ``integral promotions'' require that the abstract machine promote
the value of each variable to int size and then add the two int s and
truncate the sum." (referring to a couple of char objects) - 2.1,
non-normative example

"Therefore, for full portability the variable
c should be declared as int."
- 3.3.16.1, non-normative example

"The following pair of declarations demonstrates the difference
between a ``variable pointer to a constant value'' and a ``constant
pointer to a variable value.''" - 3.5.4.1, non-normative example

"...assigning a value to a static storage
duration variable of type volatile
sig_atomic_t" - 4.7.1.1 - normative text.

"an enumeration variable that has the same type" - A.5, non-normative
appendix

I think the normative text of 4.7.1.1
shows that "variable" is indeed a C
concept. It's a shame, in a way, since it's such a woolly term.
Did this
usage in 4.7.1.1 survive into the final C89 standard?

Yes, they all survived.
C99 has the word "variables".
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top