I'm trying to figure out how to remove all memory leaks from this code. I know this issue probably stems from the push(T value) function when using new Node<T>(value) but I don't know how to fix this.
#ifndef MYSTACK_H
#define MYSTACK_H
#include <stdexcept>
using namespace std;
template <class T> class MyStack{
template <class G> class Node{
public:
G value;
Node* next;
Node(T val, Node* n = NULL): value(val), next(n){};
};
public:
MyStack(){
head = NULL;
tail = NULL;
my_size = 0;
};
~MyStack(){
delete head;
}
void push(T value){
if(head == NULL){
head = new Node<T>(value);
tail = head;
my_size++;
}
else{
Node<T> *temp = new Node<T>(value);
temp->next = head;
head = temp;
my_size++;
}
}
// . . . (removed - brevity)
private:
unsigned int my_size;
Node<T> *head;
Node<T> *tail;
};
#endif
Any help would be appreciated! Thanks!
You need to delete all the elements in your stack. Here are a couple of ways to do this:
In your destructor, loop through all elements in your stack and delete them.
In your destructor, repeatedly call pop until the stack is empty.
Option 2 is probably simpler to code, assuming that you already have a pop function, but potentially less efficient as it will be doing extra work to ensure the stack structure is maintained while it is being destroyed.
Related
class Node
{
public:
int value;
Node *next;
};
class LinkedList
{
private:
Node *head;
public:
LinkedList(void) { head = NULL; }
~LinkedList(void){};
void insertAtHead(int);
void insertAtLocation(int, int);
void Delete(int);
void displayList();
int countList();
};
void LinkedList::insertAtHead(int new_value)
{
struct Node *newNode, *NodePtr = head;
newNode = new Node;
newNode->value = new_value;
newNode->next = NULL;
if (!head)
head = newNode;
else
{
newNode->next = NodePtr;
head = newNode;
}
cout << "Node successfully inserted at the head\n\n";
}
I didn't create any structure for the node, rather I made a class for it. But I don't know why my code is working properly when I make a newNode in the insertAtHead function by writing struct at the start of initialization, What is happening there? no, compile and run time error when the struct is written before Node. What is the concept behind this work?
There is no difference between struct and class that is relevant to this code. So you can switch them around as you wish with no consequences.
This
struct Node *newNode, *NodePtr = head;
is a C-ism. In C++ you would write:
Node *newNode, *NodePtr = head;
Moreover a struct is a class in C++. struct and class are just two different keywords. Only for default access they make a difference when used to define a class. See here for more details on that: When should you use a class vs a struct in C++?.
I read some of the other posts on this topic because there were quite a few, but they didn't really help my situation.
I am getting memory leaks in my implementation of a doubly linked list. I have to make my own so using list is not an option.
here are the two push functions I am using...
template <class T>
void dllist<T>::push_front(T val) {
node* new_node = new node;
new_node->value = val;
new_node->forward = head;
new_node->backward = nullptr;
if (head != nullptr)
head->backward = new_node;
head = new_node;
}
and...
template <class T>
void dllist<T>::push_back(T val) {
node* new_node = new node;
new_node->value = val;
new_node->forward = nullptr;
if (!head)
head = new_node;
else {
node* traveller = head;
while (traveller->forward != nullptr)
traveller = traveller->forward;
traveller->forward = new_node;
new_node->backward = traveller;
}
}
finally, here is my destructor
template <class T>
dllist<T>::~dllist() {
node* current = head;
while (current != nullptr) {
node* forward = current->forward;
delete current;
current = forward;
}
}
In main, I declare an object of type dllist called mylist and I make a few calls to push_front with some integer values and then push_back.
I am using the CRT library to check for leaks and there is a leak at each call to push_back or push_front.
I am confused because I thought I made my destructor correctly. Is there something else Im not seeing?
If anyone could point me in the right direction I'd appreciate it!
Thanks.
MRE
template<class T>
class dllist {
struct node {
T value;
node* forward;
node* backward;
};
node* head;
public:
dllist(); // default constructor
~dllist(); // default destructor
void push_front(T); // push element to the front of the list
void push_back(T); // push element to the back of the list
};
int main() {
{
dllist<int> mylist;
mylist.push_front(10);
mylist.push_front(12);
mylist.push_front(14);
mylist.push_front(16);
mylist.push_front(18);
mylist.push_front(19);
mylist.push_back(11);
mylist.push_back(21);
mylist.push_back(31);
mylist.push_back(41);
mylist.push_back(31);
mylist.push_back(41);
mylist.push_back(222);
}
_CrtDumpMemoryLeaks();
return 0;
}
template <class T>
dllist<T>::dllist() {
head = nullptr;
}
We were instructed to implement a class that uses a vector to store a queue. I came up with the following but it's not really working. Can anyone tell me what went wrong?
The values of the numbers are correctly pushed into the vec, and the first pop() works. But if I check head->getElement(), it gives a strange number. Subsequent calls to pop() also fail.
#include <iostream>
#include <vector>
using namespace std;
template<class T>
class node{
T element;
node* next;
public:
node(): next(nullptr){};
T getElement() {return element;}
void setElement(T newElement) {element=newElement;}
node* getNext() {return next;}
void setNext(node* newNext) {next = newNext;}
};
template<class T>
class queue{
vector<node<T>> vec;
node<T>* head;
int size;
public:
queue(): head(nullptr){}
void push(node<T> newNode);
node<T> pop();
int getSize() {return unsigned(vec.size());}
vector<T> getVec()const {return vec;}
node<T>* getHead() {return head;}
void setHead(node<T>* newHead) {head = newHead;}
vector<node<T>> getVec() {return vec;}
};
int main() {
queue<int> v;
for (int i=0;i<5;i++){
node<int>* newNode = new node<int>;
newNode->setElement(i);
v.push(*newNode);
}
cout<<"The elements in the vector are initially:\n";
for (int i=0; i<v.getSize();i++)
cout<<v.getVec()[i].getElement()<<" ";
cout<<"\nAfter popping, the popped element is "<<v.pop().getElement()<<endl;
}
template<class T>
node<T> queue<T>:: pop(){
node<T>* tmp = new node<T>;
tmp->setNext(head->getNext());
head=head->getNext();
return *tmp;
}
template<class T>
void queue<T>:: push(node<T> newNode){
if (head==nullptr){
node<T>* newPtr = new node<T>;
newPtr = &newNode;
newPtr->setNext(head);
head=newPtr;
}
else{
node<T>* newPtr = new node<T>;
newPtr->setElement(newNode.getElement());
node<T>* end = head;
while (end->getNext() != nullptr)
end->setNext(end->getNext());
end->setNext(newPtr);
}
vec.push_back(newNode);
}
There are many issues with your code.
First, lets fix pop. You are creating a new node tmp, setting the next and returning the same without setting the element. To fix this, you just need it to set it to head and move the head to its next.
template<class T>
node<T> queue<T>:: pop(){
node<T>* tmp = head;// = new node<T>;
//tmp->setNext(head->getNext());
head=head->getNext();
return *tmp;
}
After this you will get your element with pop. But you will get wrong element. As queue is FIFO based, you should get '0' at first pop but in your case you will not get 0. Because, your push function is also incorrect. In push, when you are pushing the first element, then you are taking the address of the node object passed which is passed by value, this leads to undefined behavior, since the node object passed would be destroyed once the function finishes. Also, in the else part of your push you are setting the next of end to its own next and hence it will go into infinite loop. Below is the corrected implementation.
template<class T>
void queue<T>:: push(node<T> newNode){
if (head==nullptr){
node<T>* newPtr = new node<T>;
newPtr->setElement(newNode.getElement());
//newPtr = &newNode;
//newPtr->setNext(head);
head=newPtr;
}
else{
node<T>* newPtr = new node<T>;
newPtr->setElement(newNode.getElement());
node<T>* end = head;
while (end->getNext() != nullptr)
end = end->getNext();
end->setNext(newPtr);
}
vec.push_back(newNode);
}
Lastly, there are many memory leaks in your code. You are creating a new node far more number of times than needed and also not deleting them. As, you can see now that in case of push, you just need to pass the element T and it would suffice. You don't need to pass a new node every time.
Also, try using smart pointers as it will manage a lot of things on its own.
I've start implementing some data structures in C++, starting from Linked Lists.
Coming from a Java background, I'm still wrapping my head around pointers and objects lifespans.
LinkedList:
struct Node
{
int data;
Node *next;
};
class LinkedList
{
private:
Node *head;
Node *tail;
int length;
public:
LinkedList();
~LinkedList();
void addToHead(Node &newHead);
void popHead();
void printList();
};
and then I've implemented it like this:
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
length = 0;
}
LinkedList::~LinkedList(){}
void LinkedList::addToHead(Node& newHead)
{
newHead.next = head;
head = &newHead;
length++;
}
void LinkedList::popHead()
{
Node *currHead = head;
head = head->next;
length--;
}
void LinkedList::printList()
{
Node *curr = head;
while(curr)
{
curr = curr->next;
}
}
Lastly there's a simple main:
int main()
{
LinkedList list;
Node n1 = {3};
Node n2 = {4};
Node n3 = {5};
list.addToHead(n1);
list.addToHead(n2);
list.addToHead(n3);
list.printList();
list.popHead();
list.printList();
return 0;
}
This a rather naive implementation, and I was wondering if I had to provide a proper destructor which deletes the Node* pointers upon iteration.
Whenever I've tried to add it, the program results in a memory error, and I was thinking that the memory being allocated is being also deallocated at the end of the main, since all the Node*s live there.
Should I fix my destructor? Should I change the whole interface?
Thanks in advance!
Although there are no memory leaks in your code as it stands, I think you should change your interface.
Your linked list isn't doing what you probably think its doing - taking ownership of its contents. A linked list that doesn't own its contents is a strange beast and probably something you did not intend.
One easy way to make it take ownership is to change your design to use std::unique_ptr instead of raw pointers. Your addToHead function would then be change to take std::unique_ptr r-value references pointers (or simply raw pointers that create new std::unique_ptr internally if that's too advanced)
Here is your implementation changed to use std::unique_ptr. Its a bit rough-and-ready, but should get you on your way:
#include <memory>
struct Node
{
Node(int i) : data(i)
{}
int data;
std::unique_ptr<Node> next;
};
class LinkedList
{
private:
std::unique_ptr<Node> head;
Node *tail;
int length;
public:
LinkedList();
~LinkedList();
void addToHead(std::unique_ptr<Node>&& newHead);
void popHead();
void printList();
};
LinkedList::LinkedList()
{
head = NULL;
tail = NULL;
length = 0;
}
LinkedList::~LinkedList(){}
void LinkedList::addToHead(std::unique_ptr<Node>&& newHead)
{
newHead->next = std::move(head);
head = std::move(newHead);
length++;
}
void LinkedList::popHead()
{
head = std::move(head->next);
length--;
}
void LinkedList::printList()
{
auto* curr = head.get();
while(curr)
{
curr = curr->next.get();
}
}
int main()
{
LinkedList list;
list.addToHead(std::make_unique<Node>(3));
list.addToHead(std::make_unique<Node>(4));
list.addToHead(std::make_unique<Node>(5));
list.printList();
list.popHead();
list.printList();
return 0;
}
I've read through similar problems, but I can't find anything that specifically addresses my problem (or I simply don't understand the other solutions)
I am trying to implement a template Stack class, and am having an issue when trying to push to the stack. here is my Stack.cpp:
#ifndef _STACK_H
#define _STACK_H
#include <string>
#include <stdio.h>
#include "Node.cpp"
template<typename T>
class Stack{
private:
Node<T>* mHead;
public:
Stack();
~Stack();
void push(T data);
};
template<typename T>
Stack<T>::Stack(){
mHead = NULL;
}
template<typename T>
Stack<T>::~Stack(){
delete mHead;
}
template<typename T>
void Stack<T>::push(T data){ // <-- having trouble with this method
Node<T>* temp = new Node<T>;
temp->data = data;
//if head is already empty, just create 1 Node
if(mHead==NULL){
printf("if working\n");
mHead = temp;
}else{
printf("else working\n");
//rearrange Nodes
temp->next = mHead;
mHead = temp;
}
printf("success\n");
}
#endif
push() gets called from a function in the manager class:
void Manager::testPush(){
Stack<int> test;
int number = 3;
test.push(3);
}
When I run the code and call managers testPush() method, i get the following being printed:
if working
success
*** Error in `./assignment': free(): invalid pointer: 0x0000000000f11078 ***
[1] 14976 abort (core dumped) ./assignment
I'm not sure what free() means, and what could possibly be causing this error/abort
It seems that you forgot to set data member next to NULL in node temp.
template<typename T>
void Stack<T>::push(T data){ // <-- having trouble with this method
Node<T>* temp = new Node<T>;
temp->data = data;
temp->next = NULL; // <=== add this statement
//if head is already empty, just create 1 Node
if(mHead==NULL){
printf("if working\n");
mHead = temp;
If the class Node has a constructor with two parameters or if it is an aggregate you could write simpler
template<typename T>
void Stack<T>::push( const T &data )
{
mHead = new Node<T> { data, mHead };
}
Take into account that the destructor of class Node must delete all nodes in the stack.
This function
void Manager::testPush(){
Stack<int> test;
int number = 3;
test.push(3);
}
also looks questionably because test is a local variable of the function. The stack can be used only inside the function.