Bob John
Bob John

Reputation: 3878

How can you avoid leaking memory when removing from a doubly-linked list?

Suppose I have a doubly-linked list such as

class list
{
    /*...*/

private:
    struct node
    {
       node* prev;
       node* next;
       int* value;
    }

    node* first; //NULL if none
    node* last; //NULL if none

    /*...*/
}

If I want to write a function that removes the first node and returns a pointer to its value, will this implementation leak memory?

int* returnFrontValue()
{
   if(list_is_Empty())
        throw -1;
   else
   {
        node* v = first;
        int* returnMe = v->value;

        first = first->next;
        if(!first)
            last = NULL;

        delete v;
        first->prev = NULL;

        return returnMe;
   }
}

I'm curious if this implementation leaks memory because returnMe points to an int that is dynamically allocated. Would it be better to have an int returnMe = *(v->value); and return &returnMe; at the end instead?

Do I have to delete v->value; explicitly before I delete v;? I'm confused as to how deleting memory works when you have various pointers.

Upvotes: 0

Views: 182

Answers (1)

Stack Overflow is garbage
Stack Overflow is garbage

Reputation: 247989

We can't see how the int was allocated, but I'll take your word for it that it was dynamically allocated (as a separate allocation from the node, which you delete).

In that case no, you haven't leaked anything yet, but you're tempting fate. It's not a leak because a pointer to the int still exists, so it can still be deleted. But now the responsibility rests with the caller. If I call returnFrontCaller, I get a pointer to a value, which I then have to call delete on when I'm done with it.

That's not very intuitive. Generally new/delete calls should be matched in the same place. If I call new, I also call delete. If the new call happened elsewhere, I wouldn't expect that calling delete was my responsibility.

But why is the value dynamically allocated at allWhy do you store anint*instead of anint`? Why does the function return a pointer to the int, instead of a copy of it?

If you made that change, no memory management would be necessary. The caller would get an int, and wouldn't have to worry about "who calls delete".

Alternatively, you could use a smart pointer class to wrap it, and to handle the memory management.

Upvotes: 2

Related Questions