theEpsilon theEpsilon - 11 months ago 40
C++ Question

Would deleting a Linked List recursively cause a stack overflow?

I have a linked list build out of


class Node {
Node(string data);
Node* GetNext() const;
void SetNext(Node* nextNode);
string data;
Node* next;

The destructor is defined below:

Node::~Node() {
delete next;

Where the destructor should be called on the head

My question is this: would deleting the singly-linked list like this cause a Stack Overflow on large lists (it works fine on small i.e., < 10 size lists). If it does, would it be better to use an iterative solution, like

while (head->GetNext() != 0) {
Node* temp = head->GetNext();
delete temp;
delete head;

where there is no defined constructor for

Answer Source

The problem with your solution is that the stack frames are continuously building up on the stacks, for each call to the ~Node() method. Take an example of 3 Node objects, starting at, say 0x01. Deletion of these has the following stack frame backtrace (I assume each Node object contains 1 bit of information, which isn't true, but it makes the list a bit neater):

 (0) Node (0x01): ~Node
 (1) Node (0x02): ~Node
 (2) Node (0x03): ~Node

So, for a million Node objects, you will have a million stack frames before the first one even completes. Each stack frame takes up space on the stack, so, yes, you could run out of stack space.

The iterative solution doesn't suffer from this problem, because, for each iteration, the call to delete a Node completes before the next Node deletion routine runs. This means that you have a single function call on the stack during each iteration (plus or minus the amount you need to complete that function call, but in particular, it's not recursive).

In addition to that problem, there's another problem that's been raised, and that is that you don't have any way of deleting just a single Node object. You can either delete the whole list or part of the list. Imagine what would happen if a client had a reference to Node (0x02) in the previous example, and called delete node. In this case, Node (0x02) and Node (0x03) would be deleted, but Node (0x01) would _still have a reference to the pointer to the memory for Node (0x02). Dereferencing this would cause a crash.