I would like to know Where arugment passed to main() gets stored in memory ,Do they simply get store in stack .If so then how k's value is initialize in below code
#include<stdio.h>
int main(int k)
{
if(k<10)
printf("%d ",main(k+1));
return k;
}
O/p: 10 9 8 7 6 5 4 3 2
It'll typically be stored wherever parameters to other functions get stored -- which might be stack, register, or somewhere else entirely. Just for a few examples: on a SPARC, it'll almost certainly be a register; on an x86 (in 32-bit mode) it'll typically be the stack; on an IBM mainframe, it'll normally be in a stack frame that's dynamically allocated from the heap and linked together into a linked list that's constructed/destroyed FIFO fashion.
Also note that it can/does vary even on a single machine with a single compiler -- e.g., Microsoft VC++ can pass it on the stack or in a register depending on what compiler flag(s) you use. When/if you pass it in a register, it'll (probably) be pushed on the stack inside the function anyway (to allow the recursion).
As an aside, I'll also note that while your codecalling main is perfectly legal C, you are not allowed to call main in C++.
Edit: As for the initial value, that first parameter is traditionally called argc, and tells you how many arguments were passed on the command line. If you invoke it (as you apparently have) with no command line, it should normally start out as 1 (the one argument being the name of the program itself, traditionally passed as argv[0]). If, for example, you invoked the program something like:
prog a b c d e f g h i j k l m
It would normally exit without printing anything, because on the first entry to main, the parameter would be greater than 10 so the body of the if statement would never execute.
parameters to main() are like arguments to any other method. They are part of the stack (depending on the processor, that could be in memory, or in a CPU register). In this case, when you call main(k+1), the result of k+1 is put on the stack before the recursive call is performed.
Note that the behavior of this is undefined since calling main() from within a C program is unspecified.
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.
Like every function is put on a stack frame for its execution and it is flushed after its completion. So, any local variable wont be available to other functions. But then how are we able to return a local variable to the caller?
int pickMin( int x, int y, int z ) {
int min = x ;
if ( y < min )
min = y ;
if ( z < min )
min = z ;
return min ; }
The above code works fine. However the in the below code, compiler does give a warning message- "warning: function returns address of local variable [-Wreturn-local-addr] return a; " but it prints a garbage value at the end, which I think is fine because the variable has already been flushed. But why didn't that happen in the ABOVE program?! I mean, it should also have returned me a garbage value.Moreover, I know that the problem in the below code can be solved using malloc, and then returning that value. :)
int *returnarray(){
int a[10]; int i;
for(i=0;i<10;++i){
a[i] = i;
}return a;}
C passes everything around by value. In your first snippet, return min returns an int variable. Its value is returned. The second snippet consists of return and an array name, which decays into a pointer.
The value that is returned, is the memory address of a local variable. The function where this variable existed has returned, though, and accessing the memory that this function used then invokes undefined behaviour.
The way to handle this kind of situation (ie: needing to return an array) is either by passing the target array to the function as an argument, or by allocating the memory using malloc and returning that pointer.
Heap memory is a tad slower, more error prone, and requires you to look after it though. Still, here's an example of both approaches
create_fill allocates, assigns and returns a pointer to the heap memory, fill_array doesn't return anything, but expects you to pass an array (which decays into a pointer), and a max length to fill. The advantage being: stack memory doesn't require as much care, and will outperform the heap.
The return statement des exactly that: it copies the value of a variable, and leaves it on top of the stack so the calling function can use it. Now, in C this works for simple values, not for arrays because your "array variable" a is actually the address of its first value only.
First, read carefully call stack wikipage. There are nice pictures on it. See also the x86 calling conventions wikipage.
Then, the result (of some C function) often goes thru a register when returned (or, for large struct-s, in a stack space allocated by the caller).
Details are ABI specific. For Linux on x86-64 (in 64 bits), the x86-64 ABI mentions the %rax register to return a result (in common cases, but when the result is a large struct the caller passes an address for it).
BTW, in principle, I believe that nothing in the C99 standard requires a stack, but I know no C implementations without a call stack (generally the processor stack, i.e. thru the stack register).
In first case you return value of a variable.
While, in second case you return address of a local variable which as you correctly said is not available for other functions. In C, the name of an array is the base address of that array. Hence in second case, "base address of array" is copied to any variable/pointer, which is assigned the return value of that function
#include<stdio.h>
int *fun();
int main()
{
int *ptr;
ptr=fun();
printf("%d",*ptr);
printf("%d",*ptr);
}
int * fun()
{
int k=4;//If auto then cannot print it two times.....stack will be changed
return(&k);
}
O/P: 4
-2
Calling printf() for the first time prints the correct value.
Calling any function (even printf( ) ) immediately after the call to fun( ). This time printf( ) prints a garbage value. Why does this happen?Why do we not get a garbage value during the first print statement itself????
This is not behavior you can rely on; it may and likely will differ on different systems, even different versions of the compiler or different compiler switches.
Given that, what is likely happening is this: fun returns a pointer to where it stored k. That part of the stack is no longer reliable, because the function that allocated it has exited. Nonetheless, nobody has written over it yet, so the 4 is still where it was written. Then main prepares to call printf. To do so, it gets the first argument, *ptr. To do this, it loads from the place ptr points, which is the (former) address of k, so the load gets the 4 that is there. This 4 is stored in a register or stack location to be passed to printf. Then the address of the format string, "%d", is stored to be passed to printf. Then printf is called. At this point, printf uses a great deal of stack and writes new data where k used to be. However, the 4 that was passed as an argument is in a safe place, where arguments to printf should be, so printf prints it. Then printf returns. Then the main routine prepares to call printf again. This time, when it loads from where ptr points, the 4 is no longer there; it is some value that was written during the first call to printf. So that value is what is passed to printf and is what is printed.
Never write code that uses this behavior. It is not reliable, and it is not proper code.
Why does it surprise you? The behavior is undefined, but there's nothing unusual in observing what you observed.
All variables live somewhere in memory. When a variable gets formally destroyed (like local variables when function exits) the memory it used to occupy still exists and, most likely, still holds the last value that was written to it. That memory in now officially free, but it will continue to hold that last value until some other code reuses that memory for other purposes and overwrites it.
This is what you observe in your experiment. Even though the variable kno longer exists, pointer ptr still points to its former location. And that former location still happens to hold the last value of k, which is 4.
The very first printf "successfully" receives a copy of that value for printing. And that very first printf is actually the one that reuses the old memory location and overwrites the former value of k. All further attempts to dereference ptr will show that 4 is no longer there, which is why your second printf prints something else.
Variable k is local to fun(), means it will be destroyed when the function returns. This is a very bad coding technique and will always lead to problem.
And the reason why the first printf returns the correct value:
First of all it might or might not return the value. The thing is suppose k is written somewhere on stack memory. First time when the function returns printf might get the correct value because that part of memory might exist for a while. But this is not guaranteed.
Here is my code
#include<stdio.h>
int * fun(int a1,int b)
{
int a[2];
a[0]=a1;
a[1]=b;
//int c=5;
printf("%x\n",&a[0]);
return a;
}
int main()
{
int *r=fun(3,5);
printf("%d\n",r[0]);
printf("%d\n",r[0]);
}
I am running codeblocks on Windows 7
Every time I run the loop I get the outputs as
22fee8
3
2293700
Here is the part I do not understand :
r expects a pointer to a part of memory which is interpreted as a sequence of boxes (each box of 4 byte width - >Integers ) on invoking fun function
What should happen is printf of function will print the address of a or address of a[0]:
Seconded
NOW THE QUESTION IS :
each time I run the program I get the same address?
And the array a should be destroyed at the end of Function fun only pointer must remain after function call
Then why on earth does the line r[0] must print 3?
r is pointing to something that doesn't exist anymore. You are returning a pointer to something on the stack. That stack will rewind when fun() ends. It can point to anything after that but nothing has overwritten it because another function is never called.
Nothing forces r[0] to be 3 - it's just a result of going for the simplest acceptable behaviour.
Basically, you're right that a must be destroyed at the end of fun. All this means is that the returned pointer (r in your case) is completely unreliable. That is, even though r[0] == 3 for you on your particular machine with your particular compiler, there's no guarantee that this will always hold on every machine.
To understand why it is so consistent for you, think about this: what does is mean for a to be destroyed? Only that you can't use it in any reliable way. The simplest way of satisfying this simple requirement is for the stack pointer to move back to the point where fun was called. So when you use r[0], the values of a are still present, but they are junk data - you can't count on them existing.
This is what happens:
int a[2]; is allocated on the stack (or similar). Suppose it gets allocated at the stack at address 0x12345678.
Various data gets pushed on the stack at this address, as the array is filled. Everything works as expected.
The address 0x12345678 pointing at the stack gets returned. (Ironically, the address itself likely gets returned on the stack.)
The memory allocated on the stack for a ceases to be valid. For now the two int values still sit at the given address in RAM, containing the values assigned to them. But the stack pointer isn't reserving those cells, nor is anything else in the program keeping track of that data. Computers don't delete data by erasing the value etc, they delete cells by forgetting that anything of use is stored at that memory location.
When the function ends, those memory cells are free to be used for the rest of the program. For example, a value returned by the function might end up there instead.
The function returned a pointer to a segment on the stack where there used to be valid data. The pointer is still 0x12345678 but at that address, anything might be stored by now. Furthermore, the contents at that address may change as different items are pushed/popped from the stack.
Printing the contents of that address will therefore give random results. Or it could print the same garbage value each time the program is executed. In fact it isn't guaranteed to print anything at all: printing the contents of an invalid memory cell is undefined behavior in C. The program could even crash when you attempt it.
r is undefined after the stack of the function int * fun(int a1,int b) is released, right after it ends, so it can be 3 or 42 or whatever value. The fact that it still contains your expected value is because it haven't been used for anything else, as a chunk of your memory is reserved for your program and your program does not use the stack further. Then after the first 3 is printed you get another value, that means that stack was used for something else, you could blame printf() since it's the only thing runing and it does a LOT of things to get that numbers into the console.
Why does it always print the same results? Because you always do the same process, there's no magic in it. But there's no guarantee that it'll be 3 since that 'memory space' is not yours and you are only 'peeking' into it.
Also, check the optimization level of your compiler fun() and main(), being as simple as they are, could be inline'd or replaced if the binary is to be optimized reducing the 'randomness' expected in your results. Although I wouldn't expect it to change much either.
You can find pretty good answers here:
can-a-local-variables-memory-be-accessed-outside-its-scope
returning-the-address-of-local-or-temporary-variable
return-reference-to-local-variable
Though the examples are for C++, underlying idea is same.
#include<stdio.h>
int add(int,int);
int main()
{
int a;
a=add(5,7);
printf("%d",a);
}
int add(int x,int y)
{
x=x+y;
return(x);
}
Last night I got a doubt on return statement. See x is an auto variable defined inside the add function and as ANSI said an auto variable exists and has its lifetime only inside the function but here the return statement can make the variable a to exist even outside the function. Where does it store the value ? Stack or heap ?
Neither on the stack nor on the heap.
At least in the x86 architecture, the return value of functions is usually copied to the eax register, so it persists outside of the function. This is one of the reasons why you can't return an array but merely a pointer to it.
You can, however, return structs and other larger variables by value, in which case the compiler does some tricks by using the stack and additional registers such as edx.
What return actually does depends on the machine architecture to which the code is compiled. On a machine with registers the value of x is copied to a register. The caller will pick up the value from there and do something with it. Here, that value is copied to a variable named a.
If this code is compiled on a stack machine, the return value might be just left on the stack itself. The object code for calling the add function will look something like this:
push 7
push 5
call add
seti 0x28ccf4
add will pop the values from the stack, add them together and push the result back to the stack. (If the function deals with data structures that will not find into a slot on the stack, their addresses are pushed instead.) seti is an operation that will pop a value from the stack and assign it to the integer variable at a particular address. (Here, 0x28ccf4 is the address of a.). As the top of the stack will now contain the result of adding 5 and 7, the value of a will become 12.
It varies. In a typical case, you can count on anything up to at least the size of an int being returned in some register(s) (e.g., typically eax on x86, $v0-$v1 on MIPS, r0 on ARM).
On many machines, larger return values (e.g., a struct with several members) will result in the caller allocating space on the stack to hold the return value, and either passing a pointer to that space as a hidden argument to the function, or the function having implicit knowledge of the location of that space relative to (for example) the stack pointer when the function was entered.
Though the question is tagged C, I'll also mention that in C++ there are a few special rules about return values. Specifically, there's a return value optimization and a named return value optimization. These allow a compiler to elide code for copying a return value, even if/when (for example) the copy would normally have visible side effects. These are intended to allow optimization where the function constructs a return value where the calling code will need it, rather than constructing it locally in the function, and then making a copy back to where the calling code can use it.
It is stored in a register in most platforms I know about, but this could be changed by compiler implementation.
It is worth noticing that while return x where x is a value and not pointer, such as in you case is legitimate, if x is a pointer, you should make sure that the buffer / data it points to is valid when the function returns, otherwise it will be a valid pointer that points to invalid location.
This is most likely covered in programming language course if you are a CS student. Anyway, you can check out the Wikipedia.
And in fact, it is stored in the call stack, aka stack.
The return value of add function is copied back to 'a' in the main function. The auto variables declared within a function are present in the activation record for that function on the call stack and the activation record is removed at the end of function execution, after copying any return value back to the caller's variable..