This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 9 years ago.
I know that a dangling handle is a pointer or reference to invalid data. And I experiment with string and vector, below is my code with string:
char *p = NULL;
{
string s;
s.push_back('a');
s.push_back('b');
p = &s[0];
}
cout << *p << endl;
and the result is 'a'. It surprised me, shouldn't p be a dangling pointer? And I think that the object s should have been destructed, why can p still point to the valid content?
And I do another experiment with vector by just replacing the "string" with "vector" in the code above, and this time print nothing. So what does this mean? Is there any difference that string and vector organize their members?
You are invoking undefined behaviour, so anything can happen. In your case it just happens that the memory hasn’t been overwritten yet. It could also just segfault, wipe your harddrive or awaken the nasal demons.
Traffic laws say that if you wait for a green light, you are guaranteed to be able to cross the road safely.
You are complaining that not everyone who crosses at a red light is instantly crushed by a truck.
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:
C++ delete - It deletes my objects but I can still access the data?
(13 answers)
Closed 5 years ago.
I made a dynamic array (example):
int *a;
a = new int[3];
a[0] = 10; a[1] = 20; a[2] = 30;
Than I create a vector which stores pointers:
vector<int*> pa;
pa.push_back(&a[0]);
After I deleted (freed) the memory with "delete[] a;", I can still access to the element, that I push_backed. (cout << *pa[0]; output: 10)
Why is this happen? When I "delete[] a", it only deletes the pointer to the elements, but the elements are still accessable?
Your statement about how delete[] works is backwards. It deletes the elements but not the pointer. Continuing to use the pointer after its contents have been deleted, as you're doing, is undefined behavior. This means that literally anything is allowed to happen if you do it, so you shouldn't do it. It's by pure luck that you can still access the elements now, and bad things will happen in the future if you do it.
This question already has answers here:
Deleting a heap then dereferencing a pointer to that memory
(4 answers)
Closed 6 years ago.
I am reading Learning a New Programming Language: C++ for Java Programmers here, and there is an example on pointers that reads:
Never dereference a dangling pointer (a pointer to a location that was pointed to by another pointer that has been deleted):
int *p, *q;
p = new int;
q = p; // p and q point to the same location
delete q; // now p is a dangling pointer
*p = 3; // bad!
However, if I copy this code into a main function and add the following cout:
cout << p << " " << *p << endl;
I get the output:
0000022DC3DD0EF0 3
Which seems valid to me, I get the pointer and then the deref'd value.
Is this a typo in the webpage, or is the above code bad practice?
This is undefined behavior. You cannot access memory through a deleted pointer. That is a coincidence.
When you delete object it's memory is marked as free and can be used by other objects or even returned to OS. But nobody wastes CPU for erasing the object from memory. So p is still there but it is not yours anymore. You can't be sure what is stored in that place or even that you still have right to read the memory.
Your example is very simple so it's behaviour is predictable. When there is much work done between removal of the object and accessing it's memory, things go weird. And what's worse, such bugs are floating, sometimes code works correctly and sometimes not. So they are hard to debug.
Which seems valid to me, I get the pointer and then the deref'd value.
Among the behaviors allowed by the term "undefined behavior" is to produce results that sucker you into thinking everything is fine. (and then stop working in a more complex program giving you lots of grief because you believe that this can't possibly be the problem)
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:
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.