0

I was implementing a LinkedList using C++, and I seem to have forgotten a few things when dealing with dynamically allocated memory.

I have a node class:

class Node {    
  public:
  Node(int d) {
    data = d;
    next = NULL;
  }

  Node(int d, Node* n) {
    data = d;
    next = n;   
  }

  int data;
  Node* next;
};

and in my LinkedList class, I have the following method:

void remove(int n) {
    Node* current;
    current = head;
    Node* previous = NULL;

    while ( current->data != n && current->next != NULL)  {

        previous = current;
        current = current->next;
    }

    if (current->data == n) {
        previous->next = current->next;
        current->next = NULL;
        delete current;
    }
    else {
        std::cout << "Node not found" << std::endl;
    }
}

I seem to have forgotten..When I do delete current does that delete the Node ? Like the actual object that the pointer current points to? Or does it just delete the pointer? Or does the deletion of a pointer pointing to dynamically allocated memory using delete delete both the pointer and the object? Or do I need to have defined a Node class destructor for that?

Johan
  • 3,728
  • 16
  • 25
FrostyStraw
  • 1,628
  • 3
  • 25
  • 34
  • The `delete` expression will invoke destructor for the object being pointed to, and free the memory that object was residing in. – M.M Oct 30 '15 at 09:50
  • Are you actually using new to allocate the object? – g24l Oct 30 '15 at 09:59
  • 1
    One other bug: Check what happens when the item to delete is the first one in the list... – Roddy Oct 30 '15 at 10:03

6 Answers6

2

It just deletes the struct -in your case node- it points to, you can still use that pointer -make it point to another node-, in fact there's no way delete the pointer itself since it's allocated on the stack. it's automatically "deleted" when you leave the function.
p.s: no need to set current->next to null

hassan arafat
  • 657
  • 5
  • 15
0

Delete just free's the memory pointed to. This has the following implications:

  • You are not allowed to access the memory at this location (use after free)
  • The amount of memory you needed for your Node object is free, meaning your program would use less RAM.
  • The pointer itself points either to a non-valid location or NULL, if you follow best practise and set it to NULL manually.
  • The data at the memory location where your object was can be overwritten by any other task that has a valid pointer on this location. So technically the Node data still remains in memory as long as nobody else overwrites it.
flowit
  • 1,382
  • 1
  • 10
  • 36
  • @graham.reeds that's debatable. A few books recommend it but it is a waste of space imho – M.M Oct 30 '15 at 09:51
  • Not according to [ES.47](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-nullptr). The only time I use NULL is when I spelunking in some old WinApi code to keep the style the same. – graham.reeds Oct 30 '15 at 09:57
  • @graham.reeds Yes, prefer `nullptr` to `NULL`. But I don't see any need to clear the `current` pointer to either here. – Roddy Oct 30 '15 at 10:16
  • @Roddy there's no _need_ to clear the pointer in this case nor in many other cases. The reason it's considered good practice is because it is often much easier to detect invalid use of a null pointer than it is a dangling pointer, and the nature of the failure/error that it causes is much more predictable. So if you happen to change the code later and accidentally de-reference the pointer, you get a better result. – davmac Oct 30 '15 at 11:37
  • @davmac are you guys referring to when I do current->next = NULL; when I remove the node? – FrostyStraw Oct 30 '15 at 17:09
  • @FrostyStraw, no, we are saying that you _could_ set `current = NULL;` after you `delete current;` and some of us are saying that this would be good practice. :) – davmac Oct 30 '15 at 17:17
  • @davmac ok makes sense. well the reason I did current->next = NULL is because I figured the node being deleted didn't need to be pointing at anything. But if I do delete, it deletes the Node anyway, which includes deleting the pointer (the one that's a Node data member) pointing to the next node, right? – FrostyStraw Oct 30 '15 at 17:35
  • @FrostyStraw right, deleting an object destructs and releases the storage for all the members (since the storage for the members is part of the storage for the object itself). I wouldn't say this is exactly the same as "deleting the pointer" but it's probably what you meant. – davmac Oct 30 '15 at 19:24
0

Assuming that you have allocated your object using new delete on a pointer does the following:

  1. calls the destructor of the object
  2. request that the memory is free ( when that happens is actually implementation dependent )

At some point the memory manager will free and mark it as non-accessible by the process.

Thus it is up to you to set the pointer after calling delete to an agreed value. The best practice it to set it as nullptr for the latest compilers.

Community
  • 1
  • 1
g24l
  • 3,055
  • 15
  • 28
0

delete p causes the object pointed to by p to cease to exist. This means that

1, If the object has a destructor, it is called; and 2. p becomes an invalid pointer, so that any attempt to dereference it is undefined behaviour.

Generally, the memory occupied by said object becomes available to the program again, though this is really an implementation detail.

The phrase "delete the pointer" is normally a sloppy shorthand for "delete the object pointed-to by the pointer".

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

It does delete the actual structure pointed to by current. Pointers remain intact. No need for defining destructor.

The delete operator is to be applied to pointer to object. The pointer is an address of memory on heap allocated by calling new. Internally there is just table of addresses allocated by new. So the key to free such memory is just that address. In your case such address is stored in variable of type pointer to Node named current.

There are few problems in your code. The problematic one is that you have no posibility to tell whether node stored in current is actually allocated on heap. It might happen that current node is allocated on stack. E.g.

void someFunction(LinkedList &list) {
  Node myLocalNode(10);
  list.add(&myLocalNode);
  list.remove(10); //<-- disaster happens here
}

The same applies to statically allocated global variables.

You must take care of extreme cases. Think about what happens when deleted object is the first one, pointed by variable head. By deleteing its memory you end up with dangling pointer in head, pointing to either unallocated memory or memory used by someone else.

My third objection is to writing such structure at all. I hope it is just some school excercise, because in any other cases you should (almost must) use some existing list like std::list from C++ STL.

Číma
  • 11
  • 4
0

Whenever you call delete on a pointer variable, the object to which it is pointing to gets deleted from the memory, however the 4 bytes allocated to the actual pointer variable (in your case, the current variable), the 4 bytes will be freed only when the variable will go out of scope, ie At the end of the function