This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Returning the address of local or temporary variable
Can a local variable's memory be accessed outside its scope?
#include<iostream>
using namespace std;
int *p = NULL;
void
fun(void){
int i = 10;
p = &i;
}
int
main(void){
fun();
cout<<*p<<endl; //#1
cout<<*p<<endl; //#2
return 0;
}
I think #1 and #2 will output the same, but why #1 output 10 and #2 output a random number?
This is just undefined behavior. You're working with a pointer to a local variable, after that variable has gone out of scope. Anything could happen.
This is indeed a dangling pointer.
You are assigning p to point to an automatic (local) object. Once fun has returned, the object no longer exists, and attempting to access it through p gives undefined behaviour.
If you're interested in why you observe that particular behaviour: on most platforms, the stack frame of fun will still exist until another function is called. So reading p for the first call to << is quite likely to find the old value of i. After calling <<, the old stack frame has most likely been overwritten, so reading p will find an arbitrary value. But none of this is behaviour you can rely on; accessing the dead object could cause a crash, or any other behaviour.
Yes, p becomes a dangling pointer the moment fun() returns.
You are saving a pointer to a variable that is out of scope. Thus, the behavior is undefined. It can print anything, or even crash your application. Or even make your computer explode.
Your function is returning a pointer to something that gets over-written:
int i = 10;
p = &i; // This line
Because i is a local variable.
Related
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 1 year ago.
While reading about the dangling pointers, I came across some examples and concepts of dangling pointers. Basically, Dangling pointers are those pointers that used to point to some valid memory address but that memory address is no longer valid(local variables, releasing the memory).
So I tried the example:
int* fun(){
int a=100;
return a&;
}
int main() {
int *a =fun();
printf("fun %d",*a);
}
Which gives the error that: address of local variable is returned and it is in sync with dangling pointer concept.
But I slightly modify this code to:
int* fun(){
int a=100;
int* var=&a;
return var;
}
int main() {
int *a =fun();
printf("fun %d",*a);
}
This one works without any error.
My doubt here is that, fun() returns a int pointer and this pointer contains the address of the local variable a. After the function returns back the memory of a should be released then why does this code works without any error.
Also on my system this following don't work:
int main() {
int* x;
{
int y = 3;
x = &y;
}
*x = 56;
printf("jsdf");
}
This being the standard example to demonstrate dangling pointers.
Any one please let me know where my thinking is wrong and what happening behind the scene.
PS: I am using windows10, MinGW compiler with VSCode.
First two examples are equivalent, and in all examples a dangling pointer is used. The compiler doesn’t show you the error in the second example because it is not required to do so, but it is nevertheless invalid, its behavior is undefined. And undefined means undefined, i.e. anything is allowed, including seemingly valid behavior, but more likely data corruption, crashing, or whatever (a.k.a. nasal demons).
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 6 years ago.
Lets say this is the snapshot I want to talk about. In this code, main function calls 'foo' which returns address of locally declared variable 'a'. I was under the impression that locally declared variables de-allocates the memory when they go out of scope. Variable 'a' should be de-allocated after call to foo is done and there should not be anything left related to 'a'. But in this case, it seems to be breaking that basic assumption. What is going on underneath?
int* foo() {
int a = 5;
return &a;
}
int main() {
int* p = foo();
// Prints 5
std::cout << "Coming from foo = " << *p << std::endl;
*p = 8;
// Prints 8
std::cout << "Setting explicitly = " << *p << std::endl;
}
Your code invokes undefined behavior. As aptly as it is named, it is not defined, meaning you may get the expected result or you may not. What you should do is not rely on such results since they are not well-defined. You may feel lucky for getting expected results, but believe me, it's a trap!
It depends on your machine/compiler what value is printed. The deallocation of stack doesn't mean what was there earlier got erased. It just means that area has become invalid. That means the behavior is not guaranteed when you try to access those addresses. In your case, it just happens that the location used for storing the local variable a has not been overwritten.
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 7 years ago.
Is there any thing wrong in the following code?
#include <iostream>
using namespace std;
int* pointer;
void assign() {
int a = 2;
pointer = &a;
}
int main() {
assign();
cout<<*pointer<<endl;
}
According to my knowledge, 'a' exists in stack memory when executing assign(). Hence, after function assign() runs, the memory allocated to 'a' should be released. But in assign(), the address of 'a' is allocated to 'pointer' which exists in data segment. 'pointer' exits in the whole life of this program.
But after assign(), we print out *pointer whose corresponding variable has been released before. Is there any thing wrong will happen? Or is it a undefined behavior?
In fact, the above program can run correctly to print out the right value.
Yes, this is undefined behavior.
The only reason that you "correctly print out the right value" is that because on most common architectures, the formerly vacated address on the stack where the variable existed does not get overwritten or scribbled over by the remaining code in main() that gets executed here.
The code in main() would typically dereference the pointed to the address on the stack before constructing the stack frame for the operator<<() function call.
You get a correct value because the CPU does not yet use the location of variable (a). But if before you print the pointer the CPU need the location of the variable (a), you well get a wrong value.
This question already has answers here:
Dereferencing a null pointer
(5 answers)
Closed 8 years ago.
class A {
public:
int value = 1;
void foo() { ... };
};
int main() {
A *a = NULL;
int temp = a->value; // Crash!
a->foo(); // OK
}
What happened after I assigned the pointer NULL to a pointer variable? I thought nothing can be done until I allocate a memory to it by new. However, it still can call member function foo(), but crashed when calling member variable.
Could anyone tell me what's going on here? Thanks!
Both invoke Undefined Behavior, irrespective of the behavior you're observing, because when it is UB, anything is possible.
However, one explanation why it does't crash in the second case, possibly because the call:
nullptr->foo(); //a == nullptr, becomes implicit 'this' inside foo()
is translated to:
foo(nullptr); //the implicit 'this' passed as first argument
by the compiler, which seems fine (to the compiler), as you're not accessing any member data inside the function. If you access member data, the chance of getting it crashed increases. The compiler is just being tolerant of your wrongful deeds as long as it can.
de-referencing NULL pointer is undefined behavior. You are unlucky that you got through it in second statement.
In this case, it appears to work because the this pointer, which does not point to a valid object, is not used in foo .If it happened to refer to this there would have been one less post on stack overflow.
This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 9 years ago.
int main()
{
float* ptr;
{
float f{10.f};
ptr = &f;
}
*ptr = 13.f;
// Do more stuff with `*ptr`...
}
It it valid or undefined behavior to use/access *ptr?
I tested situations similar to the above example and everything seems to work as if the lifetime of the variable in the nested block was extended thanks to the pointer.
I know that const& (const references) will extend the lifetime of a temporary. Is this the same for pointers?
It's undefined behavior because you are accessing an object that has been deallocated.
The variable f is declared within that specific block of scope. When the execution flow reaches:
*ptr = 13.f;
the object has been deallocated and ptr points to the old address of f.
Therefore no, the lifetime of f has not been extended.
The float will go out of scope and your pointer will reference a non-allocated memory region -> using it will lead to UB.