-2

In context to what is written in this article

http://gribblelab.org/CBootcamp/7_Memory_Stack_vs_Heap.html#sec-6

A key to understanding the stack is the notion that when a function exits, all of its variables are popped off of the stack (and hence lost forever). Thus stack variables are local in nature.

So, all the variables that belong to that function in the stack are popped off, except maybe the value which is being returned to the function( or maybe reallocated for parent function?), or if it is not static.

But this particular program works completely fine.

#include<stdio.h>

int* func()
{
int a=6;
int *b;
b=&a;
printf("in func - %d \n",*b);

return b;
}

void func2()
{
    int a,c;
    a=99;
    c=2*a;
    printf("in func 2 - %d \n",c);
}

void main()
{
int *b;
b=func();
func2();
printf("in main - %d",*b);
}

Output:

C:\Users\Shaurya\Desktop>gcc asw.c

C:\Users\Shaurya\Desktop>a
in func - 6
in func 2 - 198
in main - 6
C:\Users\Shaurya\Desktop>

I figured the variables that are allocated by the user(using calloc, malloc,realloc) is accessible to other functions because they are in the heap, as the article says. But if we make a pointer to a local variable which is in the stack, and return that pointer, then also the variable is accessible in other function.

Shaurya Chaudhuri
  • 3,772
  • 6
  • 28
  • 58

2 Answers2

3

By returning the address of a local variable (and trying to dereference it in the caller), your program invokes undefined behavior. One possible outcome of undefined behavior is that your program appears to work correctly. However, if you change your code to call another function (especially one that creates and sets local variables) in between the calls to func and printf, you'll probably get a different result.

The memory cell1 that a used to occupy obviously still exists, and will contain the last value of a until something else overwrites it. You just happened to access that memory cell before anything else got to it.


1. We're talking virtual memory here, not physical memory.
John Bode
  • 119,563
  • 19
  • 122
  • 198
  • Doesn't seem to work. Should i try a larger Function? Results have been posted as an edit. – Shaurya Chaudhuri Oct 14 '14 at 20:02
  • @John Bode Not clear why the "memory" footnote. The memory cell that `a` used still exists even if physical memory, and will contain the last value of `a` until something else overwrites it (or power cycle). – chux - Reinstate Monica Oct 14 '14 at 20:25
  • 1
    @ShauryaChaudhuri: It can be any number of reasons; again, the point of this is that the behavior of `func` is *undefined*, and pretty much any result (including appearing to work correctly) is possible. You should not rely on this behavior being repeatable or predictable. Returning the address of an `auto` variable and attempting to dereference it ouside of the variable's lifetime is a coding error, full stop. – John Bode Oct 14 '14 at 20:47
  • @chux: Just trying to emphasize an abstract memory model independent of any phyiscal architecture. Obviously on a system without virtual memory, we're talking about a physical memory cell. – John Bode Oct 14 '14 at 20:51
  • Seems valid enough. So the memory may or may not be edited after the function call right. That is totally unpredictable. Maybe one time it gives the o/p as expected, sometime other it might overwrite the previous stack memory space and give a whole different o/p. Am i right on understanding this? – Shaurya Chaudhuri Oct 14 '14 at 20:55
  • @ShauryaChaudhuri: Yes. The *exact* output and the reason for it will vary, but not in a way that's generally predictable. – John Bode Oct 14 '14 at 20:57
  • @ShauryaChaudhuri That's it exactly. Problems like this are ugly for the exact same reason that prompted you to post the question in the first place: Casual slip-ups can go unnoticed for a long time, because you may get expected behavior all throughout your testing. Then, when development is complete, you'll hit the corner cases. This is where static analysis and profiling tools really shine. Where I work, we use a combination of LDRA and Valgrind, and these _types_ of tools are really invaluable for any large project – Don Shankin Oct 15 '14 at 02:07
1

You are returning the address, and it appears correct because nothing has come along to replace the memory content at that location. This is not guaranteed to be the case. If you call a function between func and printf, then you'll likely get a different result

Don Shankin
  • 440
  • 3
  • 10