3

I'm little confusing about dangling pointer in C/C++

void remove(){
Node* curr = new Node(10);
Node* pt = curr;
delete curr;

// do something here
// do other thing here
}

I assume Node* pt is still dangling pointer before the function remove() is terminated?

I don't have to worry about the pointer Node* pt after remove() is terminated?

fuz
  • 88,405
  • 25
  • 200
  • 352
1234
  • 539
  • 3
  • 12
  • 1
    `pt` is a variable local to this function; after control passes out of the function, you don't have to worry about it. – Beta May 29 '16 at 20:55
  • 1
    There is no language called C/C++. I'm removing the C tag as this is clearly a C++ question. – fuz May 29 '16 at 21:36

4 Answers4

9

Your question seems to be based on the false assumption that there is something wrong with having a dangling pointer. There is absolutely nothing wrong with it and the attempt to set all dangling pointers to NULL or the like is an anti-pattern. Just don't dereference a dangling pointer.

In the commented portion of remove, buth curr and pt are dangling pointers since they both point to an object that has been deleted. So long as that code does not dereference them, there is no issue.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 2
    _Your question seems to be based on the false assumption that there is something wrong with having a dangling pointer_. Love it. +1 – skypjack May 29 '16 at 21:10
  • 1
    This is why I come to SO to ask for clarification, this is what SO for? – 1234 May 29 '16 at 21:22
5

When you call delete curr, the value stored in curr is unchanged, but the memory at that location has been returned to the system.

Lets walk your code line by line:

Node* curr = new Node(10);

for argument's sake, lets imagine that the memory allocated has address 0x1000, that means that curr now has a value of 0x1000.

Node* pt = curr;

pt now also has the value (points to location) 0x1000.

delete curr;

This returns the memory at location 0x1000 to the system. HOWEVER, at this juncture both curr and pt both still contain the value 0x1000.

They are both dangling pointers.

Dangling pointers are unavoidable when you use raw pointers, and they are not implicitly bad. You just have to be careful not to use a dangling pointer or return one.

void badfunc() {
    char* p = new char[10];
    delete p;
    return p;  // use of dangling pointer
}
kfsone
  • 23,617
  • 2
  • 42
  • 74
3
  1. Regarding your question: "I assume Node* pt is still tangling pointer before the function remove() is terminated?"
    Yes, after calling delete curr; the block of memory previously pointed to by both Node* curr and Node* pt gets released. You should not use neither curr nor pt value after calling delete curr; (they both have the same value, and it is invalid). Do not assume that the call to delete changes the value of curr. It does not - you can check it by printing both valus before and after calling delete curr; like this:

    printf("%d, %d", curr, pt);

  2. Regarding your question: "I don't have to worry about the pointer Node* pt after remove() is terminated?"
    Indeed, after remove() finishes both Node* curr and Node* pt cease to exist. They are also out of scope (not accessible) outside of remove(). Therefore you do not have to worry about them.

  3. Also the objects/data stored in memory previously pointed to by Node* curr and Node* pt are freed/destructed by delete curr;, so you do not have to worry about it as well.

  4. Sometimes it is advised to avoid dangling pointers by setting them to NULL. This does not alleviate the problem, but it at least manifests clearly if you use such pointer by accident. This is Because trying to dereference NULL pointer results in memory segmentation fault - so you at least get a reproducible runtime error to look for your bug. Others say blindly setting every unused pointer to NULL is cluttering your code. Some wisdom is needed here to weight advantages and disadvantages.

Artur Opalinski
  • 1,052
  • 7
  • 12
0

A dangling pointer refers to a pointer that points at a no longer valid object. This need not be new/delete or malloc/free based: in fact, non-pointers can dangle. Any reference to another object or resource, where the refereence is no longer valid, but the reference 'does not know that', can be said to "dangle".

If you dereference a dangling pointer, undefined behaviour (sometimes nothing, sometimes a segfault, sometimes your hard drive is formatted, sometimes your code time travels (yes I am serious)) occurs.

So don't dereference dangling pointers.

After the delete, both pointers are dangling.

Generally, it can help to reason about a program if your code enforces the requirement variables are in known states that you can determine from their type and/or name. One example might be "do not have dangling pointers, set them to null immediately after the delete": then, if you always initialize pointers to null when created, every pointer is either valid or points to null.

Doing this with persistant data is a great idea; doing so with local variables in tiny functions often adds more noise than it helps.

Another approach is to prefer to use smart pointers, but they have their own traps. Reference counting and mark-and-sweep smart pointers turn dangling pointers into resource leaks! And unique ptr has no "observer" pointer type that is safe.

A local pointer after the end of its scope ceases to exist. It cannot be a dangling pointer, as it is not a pointer.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524