0

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.

camel.neeraj
  • 76
  • 1
  • 3
  • 2
    It's called Undefined Behaviour. Note that C++ is not designed to protect you from yourself. Have a read of [Undefined behavior](https://en.cppreference.com/w/cpp/language/ub) and also [Undefined behavior can result in time travel (among other things, but time travel is the funkiest)](https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633) The thing about UB is there is no point in asking why - cos it's Undefined. All you can do is fix the UB and move on. Someone else will be along shortly to explain stack frames and why stack memory is not returned just reused. – Richard Critten Sep 16 '21 at 15:33
  • Read this: https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope/6445794. It's about C++, but the concept is identical. – Jabberwocky Sep 16 '21 at 15:45
  • Your code appears to “work” because, when the program is preparing to pass `*a` for `printf("fun %d",*a);`, nothing has changed the stack since the function returned. Although `a` is a pointer you are not supposed to use, nothing has yet changed the memory it points to. So it is loaded into a register and passed as an argument to `printf`. If you write `printf("fun %d",*a); printf("fun %d",*a);`, likely the first `printf` call will work. But, during that call, it will use the stack and change memory. Then the second call will not work, because the memory at `a` will have been changed. – Eric Postpischil Sep 16 '21 at 16:00
  • This is the same as if you leave a bag in a hotel room, and check out. If you immediately go back for the bag, it will still be there, even though the room is no longer rented to you and you are not supposed to go into it. But, if some time goes by, another guest or a cleaner will find the bag and remove it. Then, when you go back, the bag will not be there. However, note that optimization by the compiler may change all of this behavior. The compiler might generate a program that does not manage `a` and `x` using the stack in this same way. – Eric Postpischil Sep 16 '21 at 16:01

1 Answers1

1

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).

numzero
  • 2,009
  • 6
  • 6