Memory Leak in Custom Linked List C++ - c++

For an assignment I cannot use a STL list, it must be a custom list. As the title states, I have memory leaks even though I am calling delete on the nodes \ items. I would appreciate any help on this.
List Source
template <typename T>
class DLinkList
{
private:
struct Node
{
T data;
Node *nextNode;
Node *prevNode;
Node(T data, Node *nextNode = nullptr, Node *prevNode = nullptr)
{
this->data = data;
this->nextNode = nextNode;
this->prevNode = prevNode;
}
~Node() { delete data; }
};
Node *head;
Node *tail;
public:
DLinkList();
~DLinkList();
void push_back(T data);
};
template <typename T>
inline void DLinkList<T>::push_back(T data)
{
if (isEmpty())
{
head = new Node(data);
tail = head;
}
else
{
tail->nextNode = new Node(data, nullptr, tail);
tail = tail->nextNode;
}
}
template <typename T>
DLinkList<T>::DLinkList()
{
head = nullptr;
tail = nullptr;
}
template <typename T>
DLinkList<T>::~DLinkList()
{
Node *ptr = head;
while (ptr->nextNode != nullptr)
{
Node *garbage = ptr;
ptr = ptr->nextNode;
delete garbage;
}
}
Foo Class and main
class Foo
{
public:
Foo() { i = 0; d = 0.0; }
Foo(int i, double d) { this->i = i; this->d = d; }
int getInteger() { return i; }
double getDouble() { return d; }
private:
int i;
double d;
};
int main()
{
DLinkList<Foo*> f1;
f1.push_back(new Foo());
f1.push_back(new Foo(2, 5.5));
cout << "1st Values: " << f1.at(0)->getInteger() << ", " << f1.at(0)->getDouble() << endl;
cout << "2nd Values: " << f1.at(1)->getInteger() << ", " << f1.at(1)->getDouble() << endl;
return 0;
}
From valgrind
==12125== 40 (24 direct, 16 indirect) bytes in 1 blocks are definitely lost in loss record 3 of 3
==12125== at 0x4C29203: operator new(unsigned long) (vg_replace_malloc.c:334)
==12125== by 0x400FD8: DLinkList<Foo*>::push_back(Foo*) (DLinkList.hpp:138)
==12125== by 0x400CF3: main (Source.cpp:28)
I am not sure how the memory is being lost here, I want to say that it is because it is making a copy of it and the original is being lost. If this is the case, I am unfamiliar with how to handle it.
Again, I appreciate any help in understanding this. I have tried to look through all related questions, but I did not see anything that covered this or at least I did not understand it. Thank you!

Given the other issues pointed out in the comments such as making an erroneous usage of explicitly calling the DLinkList destructor, you are doing this in main():
f1.push_back(new Foo());
f1.push_back(new Foo(2, 5.5));
You are creating an instant memory leak here on those two lines of code that can not be recovered. You are calling new but nowhere do you save the address returned from new so that you can call delete later on for that address.
So it is main that has to manage these dynamically allocated Foo objects. Something like this:
Foo* p1 = new Foo();
Foo *p2 = new Foo(2, 5.5);
f1.push_back(p1);
f1.push_back(p2);
//...
delete p1;
delete p2;
This should address the memory leak, but this is poor programming practice in this day and age of C++. You would more than likely either use
DLinkList<Foo>
and place Foo objects in the linked list, thus not requiring any manual memory management in main, or use a smart pointer and have a linked list of smart pointers, i.e.
DLinkList<std::unique_ptr<Foo>>

Alright, so I am just exhausted and was missing the simplest thing. After comparing to other lists I created, I realized that my destructor was not deleting the nodes correctly.
template <typename T>
DLinkList<T>::~DLinkList()
{
Node *ptr = head;
while (ptr != nullptr) // Not: ptr->nextNode
{
Node *garbage = ptr;
ptr = ptr->nextNode;
delete garbage;
}
}
But I do want to thank PaulMcKenzie, was a great help and also pointed out that main does need to handle the deletion of the new calls. I will up vote his and mark it.

Related

Double free in c++ destructor

I'm trying to implement a linked list in C++. The list contains a pointer to a node type allocated on the heap
The code is as follow:
#include <memory>
template<typename T>
class node {
public:
node(T v) : value(v) {}
~node() = default;
T value;
node *next;
};
template<typename T, class Allocator = std::allocator<node<T>>>
class linked_list {
private:
node<T>* head;
Allocator alloc;
public:
linked_list() : head(nullptr) {}
~linked_list() {
for (auto start = head; start != nullptr; start = start->next) {
start->~node();
alloc.deallocate(start, 1);
}
}
void push_back(T value) {
node<T> *new_node = alloc.allocate(1);
new (new_node) node<T>(value);
if (head == nullptr) {
head = new_node;
return;
}
head->next = new_node;
head = new_node;
}
};
In main.cpp:
#include "linked_list.hpp"
int main() {
linked_list<int> a;
a.push_back(4);
a.push_back(5);
return 0;
}
When I ran it I got double free detected in cache T2.
What did I do wrong with the destructor ?
This is a common newbie error. You modified your loop control variable.
for (auto start = head; start != nullptr; start = start->next)
{
start->~node();
alloc.deallocate(start, 1);
}
You modified start (deleting the memory) in the for loop's body and then tried to dereference the pointer you just deleted in its continuation expression. BOOM! You are fortunate that the runtime library was smart enough to catch this and give you the "double free" error rather than, say, launch a nuclear missile.
This is one place a while loop is better than a for loop.
while (head)
{
auto to_del = head;
head = head->next;
to_del ->~node();
alloc.deallocate(to_del, 1);
}
I've left out a lot of commentary about your antiquated techniques because they don't relate to the problem you're having, but if you really want to substitute in a different kind of allocator you should look into using allocator_traits for allocation, construction, destruction, and deallocation of your elements.
There are other problems, such as push_back being completely wrong as to where it inserts the new node. Replacing head->next = new_node; with new_node->next = head; will at least keep your program from orphaning all of the new nodes.

What is the proper way to delete a singly-linked-list in destructor?

Hello I have a bit ambiguity about writing a proper destructor:
class SLLst
{
public:
SLLst() = default;
SLLst(const SLLst&);
SLLst& operator=(SLLst);
~SLLst();
void insert(int);
void remove(int);
private:
SLLst* next = nullptr;
int data = 0;
friend void swap(SLLst&, SLLst&);
friend std::ostream& print(std::ostream&, const SLLst&);
};
SLLst::SLLst(const SLLst& rhs) :
next(rhs.next ? new SLLst() : nullptr),
data(rhs.data)
{
cout << "cpy-ctor" << endl;
}
SLLst& SLLst::operator=(SLLst rhs)
{
cout << "operator=(SLLst)" << endl;
using std::swap;
swap(*this, rhs);
return *this;
}
void swap(SLLst& lhs, SLLst& rhs)
{
cout << "operator=(SLLst)" << endl;
using std::swap;
swap(lhs.next, rhs.next);
swap(lhs.data, rhs.data);
}
SLLst::~SLLst()
{
cout << "dtor" << endl;
delete next;// is this enough?
// or should I use this code?
//SLLst* cur = next;
//SLLst* n = nullptr;
//while (cur != NULL) {
// n = cur->next;
// cur->next = nullptr;
// delete cur;
// cur = n;
//}
}
void SLLst::insert(int x)
{
SLLst* tmp = new SLLst();
tmp->data = x;
if (!next)
{
next = tmp;
return;
}
tmp->next = next;
next = tmp;
}
std::ostream& print(std::ostream& out, const SLLst& lst)
{
auto tmp = lst.next;
while (tmp)
{
out << tmp->data << ", ";
tmp = tmp->next;
}
return out;
}
As you can see if I just use delete next; in destructor then I get it called as many as nodes in the list but why many implementations use a loop to free the nodes like the commented code in destructor?
Because if I only call delete on next then the destructor will be called recursively thus I think I don't need a loop to free the nodes in destructor? is it correct?
When should I use a loop to free nodes in destructor? Thank you!
*If I run my code I'll get:
81, 77, 57, 23, 16, 7, 5,
done
dtor
dtor
dtor
dtor
dtor
dtor
dtor
dtor
As you can see dtor is called 8 times; does this mean it has properly freed all the nodes?
As you can see if I just use delete next; in destructor then I get it called as many as nodes in the list
Yep.
Because if I only call delete on next then the destructor will be called recursively thus I think I don't need a loop to free the nodes in destructor? is it correct?
Yep.
When should I use a loop to free nodes in destructor?
When you need to.
but why many implementations use a loop to free the nodes like the commented code in destructor?
Because many implementations are "C-like", and do not use destructors. So they need to.
You are making the most of C++'s object management features to "do the loop for you". Yay!
(Although, to be honest, I would still do it in a loop, because your way is potentially quite stack-heavy.)
Now go one step further and switch to std::list (or std::forward_list). 😏
Just immediately off the bat, std::unique_ptr would take care of this for you, but if you want to do it yourself, then it would look something like this, keep in mind this is a minimal example.
RAII is a very important principle in C++, it basically means, allocate when you need it, but destroy whenever you're done using it.
So if a node is being pointed to, and you delete the node that points to it, then that node should also destroy the thing it points to since it has ownership over it.
class List {
Node* first_node;
~List() {
delete first_node;
}
};
class Node {
~Node() {
delete next; // will then in turn destroy the one it points to untill one is nullptr, deleting nullptr is well defined in C++ nowadays
}
Node* next;
};
Example with std::unique_ptr
class List {
std::unique_ptr<Node> first_node;
// default dtor
};
class Node {
std::unique_ptr<Node> next;
// default dtor
};

Simple PUSH function for a C++ stack [duplicate]

This question already has answers here:
Function does not change passed pointer C++
(4 answers)
Closed 5 years ago.
I am trying to implement a simple stack in C++ using a linked list, but I am completely stumped by the PUSH() function. I've been working on it all night and it's nearly driven me bonkers. It should insert an element at the top of the stack, but every way I've tried to implement is has had issues. An excerpt of my relevant code is as follows:
template <typename T>
struct NODE{
T data;
NODE<T> *next;
}
template <typename T>
void PUSH(T x, NODE<T> *S){
NODE<T> *tmp = new NODE<T>;
tmp->data = x;
tmp->next = S;
S = tmp;
}
int main(){
NODE<int> *test = new NODE<int>;
test->data = 111;
test->next = NULL;
PUSH(99, test);
PUSH(88, test);
std::cout << test->data << std::endl;
}
I would expect the last line to print 88, but instead it prints 111. When I try to access the next element, I get a segfault so clearly I must be doing something wrong. Maybe I'm just tired, but hopefully one of you could shine some light on where I'm messing up, it seems correct to me.
void PUSH(T x, NODE<T> *S)
{
}
You are passing S by value, so any changes you make to S inside PUSH will not be visible outside.So even though you are adding elements to your stack, but your top remains the first node (111).
You can either pass a pointer to pointer to S or a reference to S
void PUSH(T x, NODE<T> **S)
{
NODE<T> *tmp = new NODE<T>;
tmp->data = x;
tmp->next = *S;
*S = tmp;
}

Pointers - passing ptr to a ptr or passing address of a ptr

I am trying to remove the left child (10) of a sample binary search tree using two methods:
Method1: By passing pointer to a pointer to the current node.
Method2: By passing address of the pointer to the current node. This does not removes the node, but calling delete corrupts the pointer arrangement, causing a crash while printing the nodes.
The tree looks like this and I am trying to delete 10 and replace it with 5
20
|
10--|---30
|
5---|
I have some understanding of pointers. But still, I am not clear with this behavior of pointers.
#include <iostream>
class Node
{
public:
Node(int key) : leftChild(0), rightChild(0), m_key (key){}
~Node(){}
Node *leftChild;
Node *rightChild;
int m_key;
};
Node* build1234(int, int, int, int);
void print(Node *);
void print1234(Node *);
void removeLeft(Node **nodePtr)
{
Node *oldPtr = *nodePtr;
if(*nodePtr)
{
*nodePtr = (*nodePtr)->leftChild;
delete oldPtr;
}
}
int main()
{
Node *demo1 = build1234(10, 20, 30, 5);
Node *demo2 = build1234(10, 20, 30, 5);
print1234(demo1);
print1234(demo2);
//Method1 - 10 is correctly removed with 5
Node **nodePtr = &demo1;
nodePtr = &(*nodePtr)->leftChild;
removeLeft(nodePtr);
print1234(demo1);
//Method2 - 10 is not removed
Node *node = demo2;
node = node->leftChild;
removeLeft(&node);
print1234(demo2);
return 0;
}
Node* build1234(int B, int A, int C, int D)
{
Node *root = new Node(A);
root->leftChild = new Node(B);
root->rightChild = new Node(C);
root->leftChild->leftChild = new Node(D);
return root;
}
void print(Node *node)
{
if(node)
{
print(node->leftChild);
std::cout << "[" << node->m_key << "]";
print(node->rightChild);
}
}
void print1234(Node *node)
{
std::cout << std::endl;
print(node);
}
Note: This question is not about BST, but pointers. If you see the two calls to removeLeft(nodePtr) and the removeLeft(&node) in the main() function.
How are these two different?
Why the second method fails to achieve the desired result?
In the first case, you are passing an address of a pointer that exists in the tree, so you are modifying the contents of the tree directly.
In the second case, you are passing an address of a variable that is local to main() instead. The tree is not modified, and deleting from the address is accessing stack memory, which is why it crashes
You're overthinking it. All you need is a function removeLeft(Node*) that unhooks the left node and deletes it, recursively:
void removeLeft(Node * p)
{
removeBoth(p->leftChild); // recurse, OK if null
delete p->leftChild; // OK if already null
p->leftChild = 0; // necessary to make recursion terminate
}
void removeBoth(Node * p)
{
if (!p) return;
removeLeft(p);
removeRight(p);
}
If you are bad with pointers consider using smart pointers.
When using smart pointers use shared_ptr<Node> instead of Node * and make_shared(new Node); instead of new Node and remove all deletes. now you can handle pointers without caring for deletes and memory corruption.

Mixing abstract classes and templates, a recipe for disaster?

I'm having problems with the following situation. I have three classes that are involved in this mixup. List, ListNode, City. I have a List<City *>, where the list will be made up of a set of ListNode<City *> (standard wrapper around the list nodes).
City is an abstract class, so there are several classes that inherit from it that could be placed in this list and accessed polymorphically. The List class has a getHead() method which returns a pointer to a ListNode that is the head.
Any city has a population, so to access the populations, I'd expect the following to work. It's not, thus my question. I broke it down into pieces to make it simpler along the way:
ListNode<City *> *head= country->city_list->getHead();
City *headnode = *head->getNode();
cout << "Test: " << headnode->getPopulation() << endl;
getPopulation() returns an integer. country is defined as List<City*> *city; Any help on how I could figure out my problem would be greatly appreciated.
edit adding more code for better idea of what I'm working with. First, ListNode:
template <class T>
class ListNode
{
public:
ListNode() {next = 0;node = 0;};
ListNode(T *t) {node = t; next = 0;};
ListNode(const ListNode &l)
{
//long copy constructor. snip.
};
T *getNode() const { return node; }
ListNode *getNext() const { return next; };
private:
T *node;
ListNode *next;
};
Now, here is what might relevant in the List class..
template <class T>
class List
{
public:
List()
{
head = 0;
size = 0;
};
List(ListNode<T> *t)
{
head = t;
size = 1;
};
List(T *t)
{
head = new ListNode<T>(t);
size = 1;
};
List(const List<T> &t)
{
// long copy constructor. snip.
};
//bunch of irrelevent methods.
ListNode<T> *getHead() const {return head;};
List &operator+=(T &t)
{
this->insert(&t);
size++;
return (*this);
};
private:
List &insert(T *t)
{
ListNode<T> *current = head;
if (current == 0)
{
head = new ListNode<T>(t);
}
else
{
while (current->getNext() != 0)
{
current = current->getNext();
}
current->setNext(new ListNode<T>(t));
}
return (*this);
};
ListNode<T> *head;
int size;
};
I have a hunch that the process of inserting might be the problem. I insert with the List class's += operator, shown in the List implementation above. It calls the private insert method shown above, as well. It looks like this:
City *somecity = new City(x,y,z); //some parameters. integers.
*city_list += somecity; // where city_list is a List.
I think you've got a variable scoping problem.
Your ListNode class contains a pointer to the node value. Your ListNode constructor takes in a pointer to the node value and saves it.
The problem is if that pointer is to a local variable that then goes out of scope. Your ListNode's node pointer is now pointing to an object that doesn't exist. e.g. in this example
addToList(List<int>& myList)
{
int x = 3;
myList += x; // pointer to x is in the list
}
// Out of scope; x no longer exists, but myList has a pointer to it.
// Accessing this node will result in an error.
There are a couple possible remedies:
Have your ListNode contain values rather than pointers. The drawback here is that you will be making copies of the values
Implement ListNode using a reference counted smart pointer which will manager the lifetime of the object.
Well, what you could do is:
ListNode<City *>* head = new ListNode<City*>(country->city_list->getHead());
City* headnode = head->getNode();
cout << "Test: " << headnode->getPopulation() << endl;
It will take the existing City (on the memory) and put it at the head of the List node, and so on.
and if you want to copy them, maybe you could just make this:
ListNode<City *>* head = new ListNode<City*>*(new City(country->city_list->getHead()));
City* headnode = new City(head->getNode());
cout << "Test: " << headnode->getPopulation() << endl;
Hope it will help you.