strange behavior in c [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can a local variable's memory be accessed outside its scope?
I recently came across the following code:
#include <stdio.h>
int* abc () {
int a[3] = {1,10,100};
return a;
}
int* xyz () {
int b[1] = {222};
return b;
}
int main() {
int *a, *b;
a = abc();
b = xyz();
printf("%d\n", *a);
return 0;
}
the output is 222. 'a' is pointing to the array declared inside the xyz().
my question is:
why is a pointing to the array declared inside xyz().
the array declared inside the function xyz() should go out of scope after the execution of the function. why is that not happening ?

2: It is happening, and the entire program has undefined behaviour. It is not a correct program, and there's little point musing about ifs and buts.

You might see 222 because the memory that was used for the local array in abc has been used for something else - the stack for the function xyz. And you're passing around an address to that memory. Make a few more function calls and *a may contain some other value.
should go out of scope after the execution of the function. why is that not happening ?
The variable has gone out of scope. Using that address outside the function is incorrect code: using a pointer to local data returned from a function is undefined behavior.

The variables a and b are automatic variables; using their adress in a other function is an undefined behavior. Anything can happen : you can't expect an output (eg, an optimizing compiler can delete some illegal code).

to return a pointer it must be a pointer to dynamically allocated variable or static or global variable.
returning a pointer to a stack variable will cause you to have pointer to the stack which will be reused when you call a new method.
it happened in your case to reuse the stack variable for another array and overwrite the old value stored when you called the first method.
try to call printf again you will see different output because the first call to printf changed the stack content.

why is that not happening ?
It does happen, just formally. Undefined behavior is not obligated to crash or to misbehave - they "anything might happen" means it can also run seemingly without any error. I just answered a similar question.

The functions abc and xyz are each passing back an address to a locally created array. Subsequent calls are mashing the memory that was previously used (and passed back to you).
These are called automatic local variables.
You'll need to declare those arrays as static or allocate the memory in a different way.

Related

Why can I access a pointer declared in a function when I'm trying to access it from outside the function in c language?

Happy new year everyone.
I am studying C language. I had a question when some code run about pointer.
#include <stdio.h>
int * b() {
int a = 8;
int *p = &a;
printf("the addr of a in b: %p\n", p); the addr of a in b: 0x7ffccfcba984
return p;
}
int main () {
int *c = b();
printf("the addr of a in main: %p\n", c); // the addr of a in main: 0x7ffccfcba984
printf("The value of ptr is : %d\n", *c ); // 8
return 0;
}
Can you feel something odd in this code?
I learned that a variables declared inside a function is deallocated at the end of the function.
However, I can still access variables outside the function
like above code when trying to access the address of "a" variable. If the deallocation is true, int a should be deallocated at the end of the b function. It is like a free is not used after variables is declared.
Is there some knowledge I am missing about deallocation?
Could you tell me why I can still access it?
Once you leave a function variables "fall out of scope" meaning they are no longer valid.
Using the address of an out of scope variable breaks that boundary and leads to undefined behaviour, as in, it's not valid to do. The &a pointer is effectively invalidated when you exit that function. If you use it then the program may behave erratically, might crash, or might work fine. It's not defined what happens.
In this trivial example you're not going to get the same behaviour as in a real program. Make another function call to a function that exercises the stack and you'll likely see some problems since the stack is being re-used.
Local variables aren't "allocated" per-se, they are simply scoped, and when that scope is exited they are invalidated.
In something like C++ there may be a deallocation process when things fall out of scope, as that language can define destructors and such, but that's not the same as C. In C they just cease to exist.
I learned that a variables declared inside a function is deallocated at the end of the function.
If the deallocation is true, int a should be deallocated at the end of the b function.
Yes. You are not wrong.
A variable will be destructured when it goes out of its scope. Although you use a pointer variable to save a pointer to that variable, accessing it through that pointer is actually an undefined behavior.
Yes, you can access it and see the results you expect because of luck or environment, but it may still cause a crash, unexpected results, etc. Because this behavior is undefined and wrong.

Address of the automatic storage class variable assigned to a local variable of another function [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
How to access a local variable from a different function using pointers?
(10 answers)
Closed 4 years ago.
#include <stdio.h>
int* function1(void);
int main()
{
int x = 10;
int *p = function1();
printf("%d\n", *p);
printf("%d\n", p);
}
int* function1(void)
{
int z;
z = 20;
z++;
return &z;
}
Variable 'z' is local to the 'function1', and is not alive after the
'function1' is terminated.
Now to access the value at the memory space of the variable 'z', its
address is returned by the function.
So, even after the termination, will the memory space of the variable
'z' will still be reserved, as the pointer accesses the variable?, in such case what will be the properties of the memory space?
Or What if some-other variable is allocated with the same memory space
of variable 'z'?
Note: GCC compiler of code blocks has compiled the program successfully, without any error and warning.
In general what you do is undefined.
However, on Intel architectures z is on the stack and after return, if you don't call any other function the value will probably still be available because the memory has not yet been reused. As soon as you call another function, the memory will probably be overwritten and so will contain garbage for you.
In general: Don't do this!
The variable z does no longer exist after the function function1 finishes it's execution. In function main you are trying to reference a memory address which has been deallocated after the function's call. This will cause undefined behavior.
When the function call happens, all your local variables will be in stack. During function call, the stack variables can be modified. When the function call returns, the stack pointer is decremented’
Hence, you will be accessing something which is not guaranteed in any way. In programming languages, this is addressed as a case of undefined behaviour, since you are overriding the rules of programming language.
In this case of function, given that you stack frame is still active and not modified by any other code, you might get the same value that you wrote to that address.
But is not guaranteed in anyway and dont assume anything not guaranteed.

C pointers and var scopes [duplicate]

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 5 years ago.
I've a question about var scopes and pointer.
That's an example function:
int *double(int a)
{
int p = a*2;
int *ret = &p;
return ret;
}
And that's the question:
After a fuction return to the caller, it should delete from the memory every variable declared in it.
In this function I only return the addres of "p" (that's declared only in the function) but when I use it in the main, for example, the space of memory allocated by the function "double" hasn't been deleted.
Why?
The memory isn't valid anymore; what happens when you access it after double has returned is undefined behavior. That means that anything is possible:
It could be that the value hasn't been overwritten by something else yet (what likely happened in your case).
It could be that something else has written something to that address, so the value is now random garbage.
It could be that your code opens up a wormhole to a parallel dimension, causing an invasion of evil space octopi that dooms us all.
So, basically, I don't recommend it.

Scope of a variable. Internal working basic

This is a very basic question about the scope of a variable suppose. I have the fiollowing code:
int main()
{
int *p;
p=func();
printf("%d",*p);
return 0;
}
int *func()
{
int i;
i=5;
return &i;
}
My question
The scope of i is finished in func() but, since I am returning the address of i will I be able to access and print5 in main()?
If not, why? does the compiler puts a garbage value in that address space (I don't think this is done).
What actually it means by the scope of a variable is ended ? Also does the memory allocated to i is freed when its scope ends?
Scope of the variable is the region where it can be accessed.
Lifetime of the variable is the time till when the variable is guaranteed to exist.
In your case lifetime of i is within the function not beyond it. It means i is not guaranteed to exist beyond the function. It is not required to and it is Undefined Behavior to access a local variable beyond the function.
The scope of i is finished in func() but, since I am returning the address of i will I be able to access and print 5 in main()?
You might, but it is Undefined Behavior. So don't do it.
If not, why? does the compiler puts a garbage value in that address space (I don't think this is done)
The compiler may put whatever it chooses to in that location, once the function returns the address location is holds an Indeterminate value.
What actually it means by the scope of a variable is ended ? Also does the memory allocated to i is freed when its scope ends?
i is a automatic/local variable and all automatic variables are freed once the scope {,} in which they are declared ends. Hence the name automatic.
It is undefined behaviour to access a variable after it has gone out of scope. This means it is not possible to say what will definitely happen. In the posted code, 5 might be printed, some other value may be printed or some other behaviour may occur (access violation for example).
Behaviour in your example is undefined. Your printf probably will output 5 but that'd be down to luck rather than good design.
In this case, when the scope of the variable is ended, further function calls may reuse the stack address &i changing the value your p variable points to.
No, accessing a variable that has gone out of scope leads to undefined behavior. The storage where thev variable used to be has been reclaimed, so you're likely to overwrite something else which can lead to crashes or just unpredictable behavior.
Your function will probably print 5, but you should never do this. It's undefined behavior since your program no longer owns the location pointed to by the pointer your return (in other words, your program no longer owns i).
Basically each time a function is called, the stack pointer is pushed down to accommodate the new stack frame. When the function call ends, the stack pointer is raised back up. This means that if a different function were to be called, it would have overlapping the same stack space as the previous function call.
To illustrate this a little better, consider this:
int main()
{
int *p;
p=func();
printf("%d\n",*p);
func2();
printf("%d\n",*p);
return 0;
}
int *func()
{
int i;
i=5;
return &i;
}
void func2()
{
int i = 1;
}
There's a pretty good chance that the output would be 5 1. This is because the second call will reuse the same stack space.
(Note that above code snippet is horrible -- you should never do something like that -- it's undefined behavior and highly implementation dependent.)
To answer your questions directly:
The scope of i is finished in func() but, since I am returning the address of i will I be able to access and print5 in main()?
No. You can, but you shouldn't. Such is the beauty of C. Depending on the compiler/OS/etc it might output 5, or it might output random garage.
If not, why? does the compiler puts a garbage value in that address space (I don't think this is done).
The space used for local variables is reused. The first half of the answer hopefully illustrated how this works. (Well, how it typically works.)
What actually it means by the scope of a variable is ended ? Also does the memory allocated to i is freed when its scope ends?
Stack based memory allocation is what's going on behind the scenes.

local memory address is valid after function return? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Can a local variable's memory be accessed outside its scope?
I was refreshing the knowledge about how memory internally works, and I faced the confusion. Here is sample code
int * func(){
int retval = 3;
return &retval;
}
int main(void){
int *ptr = func();
printf("address return from function %p and value %d\n", ptr, *ptr);
}
My understanding regards how stack memory works on a routine, is when a function was called, it is pushed on the stack. And lifetime of local variables within this routine would no longer valid once the function returns. So returning address of local variable seems like not valid, but when I test this code, it actually returns its address and still valid after the function returns.
am I misunderstanding the concept ? Appreciated any comments, Thanks.
"Testing the code" is not a meaningful way to determine if something is valid or not. Your code produces undefined behavior. One possible manifestation of undefined behavior is that the code might appear to be "working". In other words, you simply got lucky.
To answer the question: no, it is not valid to return a pointer to a local variable and it is not valid to dereference such a pointer. Any attempts to do so lead to undefined behavior.

Resources