#include<stdio.h>
#include<conio.h>
void vaibhav()
{
int a;
printf("%u\n",&a);
}
int main()
{
vaibhav();
vaibhav();
vaibhav();
getch();
return 0;
}
Every time I get the same value for the address of variable a.
Is this compiler dependent? I am using dev c++ ide.
Try to call it from within different stack depths, and you'll get different addresses:
void func_which_calls_vaibhav()
{
vaibhav();
}
int main()
{
vaibhav();
func_which_calls_vaibhav();
return 0;
}
The address of a local variable in a function depends on the state of the stack (the value of the SP register) at the point in execution when the function is called.
In your example, the state of the stack is simply identical each time function vaibhav is called.
It is not necessary. You may or may not get the same value of the address. And use %p instead.
printf("%p\n", (void *)&a);
You should use %p format specifier to print address of a variable. %u & %d are used to display integer values. And the address on stack can be same or not every time you call function vaibhav().
"a" in the function vaibhav() is an automatic variable, which means it's auto-created in the stack once this fun is called, and auto-released(invalid to the process) once the fun is returned.
When funA(here is main) calls another funB(here is vaibhav), a stack frame of funB will be allocated for funB. When funB returns, stack frame for funB is released.
In this case, the stack for funB(vaibhav) is called 3 times sequentially, exactly one by one. In each call, the stack frame for funB is allocated and released. Then re-allocated and recycled for times.
The same memory block in stack memory is re-used for 3 times. In that block, the exact memory for "a" is also re-used for 3 times. Thus, the same memory and you get the same address of it.
This is definitely compiler dependent. It depends on the compiler implementation. But I believe almost every C compiler will produce the same result, though I bet there is no specific requirement in C standard to define the expected output for this case.
Related
I just tried this as an experiment to see what values are held in d at each call.
I used gcc on an x86-64 machine.
Is there any reason why the old value of d persists after the function returns? From what I understand the call stack frame is popped off once the function returns each time, correct?
#include<stdio.h>
void fun(char ch){
char d;
printf("-- %c\n", d);
d = ch;
}
int main(){
fun('a');
fun('b');
fun('c');
return 0;
}
OUTPUT:
--
-- a
-- b
When you return from a function, the memory that was part of the stack frame of the function typically won't be zero'ed out explicitly, as that would just take up unnecessary cycles. So the memory won't be overwritten until it needs to be.
In your main function you call fun multiple times with no other statements in between. That means that nothing in main touches the memory that was used by a prior invocation of fun before calling it again. As a result, the stack frame of the second call happens to coincide with the stack frame of the first call. And because uninitialized local variables don't get a default value, d takes on whatever value happens to be in that memory location, namely what d contained when the last call to the function returned.
If you added a call to another function such as printf in between each call to fun, then that other function call would write its own stack frame on top of the stack frame of the last call to fun so you would see different results in that case.
when we declare a pointer it points to some random location or address in memory unless we explicitly assign a particular value(address of any variable) to it.
Here is code:
int *p;
printf("int is %p\n",p);
float *j;
printf("float is %p\n",j);
double *dp;
printf("double is %p\n",dp);
char *ch ;
printf("char is %p\n",ch);
j=(float *)p;
printf("cast int to float %p\n",j);
output:
int is (nil)
float is 0x400460
double is 0x7fff9f0f1a20
char is (nil)
cast int to float (nil)
Rather than printing the random location it prints (nil)
what is (nil) here ?? I don't understand the behaviour of pointers here??
Uninitialized pointer variables don't point to random address. Where they point is undefined.
In practice, they have the value what's left in the stack, which you can't know for sure. In your example, those several pointers happens to have 0 values, so they happen to be null pointer, and they print as nil.
Don't rely on such behavior, ever.
If by the "gnu" tag you mean that you're using glibc, then the reason is that the printf implementation in glibc will print "(nil)" when encountering a NULL pointer.
In other words, several of your pointers happen to have the value NULL (0), because that's what happened to be on the stack at that particular location.
Elaborating on what #yu hao has said:
Whenever a subroutine is invoked, a stack frame is allocated to the subroutine. This frame exists until return statement is encountered.
A subroutine frequently needs memory space for storing the values of local variables, the variables that are known only within the active subroutine and do not retain values after it returns. For doing so , the compiler allocate space for this use by simply moving the top of the stack by enough to provide the space. This is very fast when compared to dynamic memory allocation, which uses the heap space. Note that each separate activation of a subroutine gets its own separate space in the stack for locals known as Stack Frames.
The main reason for doing this is to keep track of the point to which each active subroutine should return control when it finishes executing. An active subroutine is one that has been called but is yet to complete execution after which control should be handed back to the point of call. Such activations of subroutines may be nested to any level (recursive as a special case), hence the stack structure. If, for example, a subroutine DrawSquare calls a subroutine DrawLine from four different places, DrawLine must know where to return when its execution completes. To accomplish this, the address following the call instruction, the return address, is also pushed onto the call stack with each call.
Coming back to your question, during its execution , the function can make changes to its stack frame and When a function 'returns', its frame is 'popped' from stack.
But the contents of stack remains unchanged in this process. Only the stack pointer gets modified to point to previous frame. So when a new subroutine gets called, new frame is allocated on top of previous one,and if the subroutine has uninitialized variables, they will print value that is stored in the memory allocated to them . Which will depend on the state of stack at that point of time.
All of your pointers are nil/ undefiend or the are just random values from the stack!
See: http://ideone.com/wwiy8F
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.
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.
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
why does printf prints 7 although the variable a was local to the function fun() and should no longer exist once the control returns from function fun().
Here is the c code
#include<stdio.h>
main()
{
int *fun();
int *c=fun();
printf("%d",*c);
getch();
}
int *fun()
{
int a=7;
return(&a);
}
output : 7
This is because even if the variable does not exist anymore, the memory location where it was has not yet been used for something else. Hence, the pointer still points to a memory location where the bits contains an int with value 7.
But this is definitely undefined behavior. You should not rely on it.
There is a difference between the language idioms and the physical operation of the hardware. In "C" words, yes, your variable should not be accessed anymore, but physically the variable a has been allocated on the stack of your program, which is not erased each time a function returns (it would take too much time), thus you can still read it.
Anyway, this is not recommended because other function calls may erase this data.
once the fun() return, the frame pointer has been set back to point the main() frame again. the pointer c pointed to some address in the memory, since the fun() has already returned, we don't know what's in the adress,but if nothing else has been written to the adress, it can still be the previous variable a. the C standard simply move the frame pointer when a function returns.
I think its because you are printing *c , which displays the value which is stored on the location i.e &a , just try to print c then you will get the address of 7 .
It is because the address is already passed to the variable c and the memory address can be read outside the function as well
#include<stdio.h>
int * fun(int a1,int b)
{
int a[2];
a[0]=a1;
a[1]=b;
return a;
}
int main()
{
int *r=fun(3,5);
printf("%d\n",*r);
printf("%d\n",*r);
}
Output after running the code:
3
-1073855580
I understand that a[2] is local to fun() but why value is getting changed of same pointer?
The variable a is indeed local to fun. When you return from that function, the stack is popped. The memory itself remains unchanged (for the moment). When you dereference r the first time, the memory is what you'd expect it to be. And since the dereference happens before the call to printf, nothing bad happens. When printf executes, it modifies the stack and the value is wiped out. The second time through you're seeing whatever value happened to be put there by printf the first time through.
The order of events for a "normal" calling convention (I know, I know -- no such thing):
Dereference r (the first time through, this is what it should be)
Push value onto stack (notice this is making a copy of the value) (may wipe out a)
Push other parameters on to stack (order is usually right to left, IIRC) (may wipe out a)
Allocate room for return value on stack (may wipe out a)
Call printf
Push local printf variables onto stack (may wipe out a)
Do your thang
Return from function
If you change int a[2]; to static int a[2]; this will alleviate the problem.
Because r points to a location on the stack that is likely to be overwritten by a function call.
In this case, it's the first call to printf itself which is changing that location.
In detail, the return from fun has that particular location being preserved simply because nothing has overwritten it yet.
The *r is then evaluated (as 3) and passed to printf to be printed. The actual call to printf changes the contents of that location (since it uses the memory for its own stack frame), but the value has already been extracted at that point so it's safe.
On the subsequent call, *r has the different value, changed by the first call. That's why it's different in this case.
Of course, this is just the likely explanation. In reality, anything could be happening since what you've coded up there is undefined behaviour. Once you do that, all bets are off.
As you've mentioned, a[2] is local to fun(); meaning it is created on the stack right before the code within fun() starts executing. When fun exits the stack is popped, meaning it is unwound so that the stack pointer is pointing to where it was before fun started executing.
The compiler is now free to stick whatever it wants into those locations that were unwound. So, it is possible that the first location of a was skipped for a variety of reasons. Maybe it now represents an uninitialized variable. Maybe it was for memory alignment of another variable. Simple answer is, by returning a pointer to a local variable from a function, and then de-referencing that pointer, you're invoking undefined behavior and anything can happen, including demons flying out of your nose.
When you compile you code with the following command:
$ gcc -Wall yourProgram.c
It will yield a warning, which says.
In function ‘fun’:
warning: function returns address of local variable
When r is dereferenced in first printf statement, it's okay as the memory is preserved. However, the second printf statement overwrites the stack and so we get an undesired result.
Because printf is using the stack location and changes it after printing the first value.