`Hello
I just wrote this code in Code Blocks and after building and running , it says that the programm has stopped working. I can't find what I have done wrong. I don't know if the problem is related to my code or is something that has to do with the compiler I am using or something else.
Please help
Library.h:
#ifndef LIBRARY_H
#define LIBRARY_H
#include <iostream>
#include <string>
using namespace std;
class Library
{
public:
struct book
{
string tittle;
int number;
struct book* next;
}* head, *tail, *ptr;
Library();
~Library();
book* searchName(book *, string);
void addNode(book *);
book *initNode(string s, int i);
void displayNode(book *ptr) const;
void displayList(book *ptr) const;
protected:
};
#endif
Library.cpp
#include "Library.h"
Library::Library() :
head(NULL), tail(NULL)
{
}
Library::~Library()
{
book *current, *temp;
current = head;
temp = head;
while (current != NULL)
{
current = current->next;
delete temp;
temp = current;
}
}
Library::book * Library::searchName(Library::book* ptr, string name)
{
while (name != ptr->tittle)
{
ptr = ptr->next;
if (ptr == NULL)
break;
}
return ptr;
}
void Library::addNode(book *newNode)
{
if (head == NULL)
{
head = newNode;
head = newNode;
}
tail->next = newNode;
newNode->next = NULL;
tail = newNode;
}
Library::book *Library::initNode(string s, int i)
{
book *ptr = new book;
if (ptr == NULL)
return static_cast<book *>(NULL);
else
{
ptr->tittle = s;
ptr->number = i;
return ptr;
}
}
void Library::displayNode(book *ptr) const
{
cout << ptr->number << ": " << ptr->tittle << endl;
}
void Library::displayList(book *ptr) const
{
if (!ptr)
cout << "Nothing to display" << endl;
while (ptr)
{
displayNode(ptr);
ptr = ptr->next;
}
}
main.cpp
#include "Library.h"
#include <iostream>
using namespace std;
int main()
{
Library a;
Library::book *ptrr;
ptrr = a.initNode("s1", 1);
a.addNode(ptrr);
ptrr = a.initNode("s2", 2);
a.addNode(ptrr);
a.displayList(a.head);
}
When you call the first a.addNode(ptrr) from main it does tail->next = newNode; (within Library::addNode), but, as tail is NULL (not assigned yet), it crashs....
Now, there could be other problems in the code, but this is most likely the first one that will make the program stop working...
Note that some stuff in your code could be simplified.
Like:
Library::book *Library::initNode(string s, int i)
{
book *ptr = new book;
if (ptr == NULL)
return static_cast<book *>(NULL);
else
{
ptr->tittle = s;
ptr->number = i;
return ptr;
}
}
could simply be:
Library::book *Library::initNode(string s, int i)
{
book *ptr = new book;
if (ptr != NULL)
{
ptr->tittle = s;
ptr->number = i;
}
return ptr;
}
And:
void Library::addNode(book *newNode)
{
if (head == NULL)
{
head = newNode;
head = newNode;
}
tail->next = newNode;
newNode->next = NULL;
tail = newNode;
}
Should be:
void Library::addNode(book *newNode)
{
if ( newNode != NULL ) // just in case
{
if (head == NULL)
{
head = newNode; // one is enough
}
if ( tail != NULL ) // to fix your crash
tail->next = newNode;
newNode->next = NULL;
tail = newNode;
}
}
Also, see user4581301 comment, the destructor code does not even compile....
Related
I have implemented a singly-linked-list where there is a SinglyList class, and struct node, node *head as private members of the class; and wrote a destructor to delete it. I used CRT library to check for memory leaks using _CrtDumpMemoryLeaks() method. When I debug the code, it shows in the debug console that memory leaks are found, which is strange since I wrote a destructor to delete it.
This is shown in the debug console:-
Here is the node class:-
struct node
{
int data = NULL;
node*next = NULL;
};
Here is the destructor:-
SinglyList::~SinglyList()
{
node*curr = head,*next;
while(curr != NULL)
{
next = curr->next;
delete curr;
curr = next;
}
}
I don't understand, how can there be memory leaks when all nodes are deleted, kindly help.
Edit:
SinglyList.hpp:-
#pragma once
#include<iostream>
class SinglyList
{
private:
struct node
{
int data = NULL;
node*next = NULL;
};
node*head;
public:
SinglyList();
void Append(const int&);
void Prepend(const int&);
void Print();
void Insert(const int&,const int&);
void Delete(const int&);
void Reverse();
bool isEmpty();
~SinglyList();
};
SinglyList::SinglyList()
{
head = NULL;
}
SinglyList::~SinglyList()
{
node*curr = head,*next;
while(curr != NULL)
{
next = curr->next;
delete curr;
curr = next;
}
}
void SinglyList::Append(const int&data)
{
node*n = new node{data};
if(!head)
{
head = n;
return;
}
node*ptr = head;
while(ptr->next)
ptr = ptr->next;
ptr->next = n;
}
void SinglyList::Prepend(const int&data)
{
node*n = new node{data};
if(!head)
{
head = n;
return;
}
n->next = head;
head = n;
}
void SinglyList::Print()
{
if(!head)
return;
node*ptr = head;
while(ptr)
{
std::cout<<ptr->data<<' ';
ptr = ptr->next;
}
std::cout<<std::endl;
}
void SinglyList::Insert(const int&pos,const int&data)
{
if(pos == 1)
{
Prepend(data);
return;
}
node*n = new node{data};
node*ptr = head;
for(int i = 1;i!=pos-1;i++)
ptr = ptr->next;
n->next = ptr->next;
ptr->next = n;
}
void SinglyList::Delete(const int&pos)
{
if(!head)
return;
node*ptr = head;
if(pos == 1)
{
head= head->next;
delete ptr;
return;
}
for(int i = 1;i!= pos-1;i++)
ptr = ptr->next;
node*temp = ptr->next;
ptr->next = temp->next;
delete temp;
}
void SinglyList::Reverse()
{
if(!head)
return;
node*curr = head,*prev = NULL,*next = NULL;
while(curr)
{
next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
head = prev;
}
bool SinglyList::isEmpty()
{
return (!head);
}
main.cpp:-
#include"SinglyList.hpp"
#include<crtdbg.h>
int main()
{
SinglyList nums{};
nums.Append(10);
nums.Append(20);
nums.Append(30);
_CrtDumpMemoryLeaks();
return 0;
}
You print the leaks before the list gets deleted. Try this instead:
#include"SinglyList.hpp"
#include<crtdbg.h>
int main()
{
{
SinglyList nums{};
nums.Append(10);
nums.Append(20);
nums.Append(30);
}
_CrtDumpMemoryLeaks();
return 0;
}
Then, you'll show the actual leaks after your list gets destroyed.
I'm wondering why my overloaded == function is not working. I'm confused about the private head. Would the private head be the head of the linked list that was made last? So if I compared the last linked list with the inputted LinkedList then wouldn't it work?
code for append
void LL::append(string pName,string phone)
{
Node *newNode = new Node;
newNode->name = pName;
newNode->phoneNumber = phone;
newNode->next = nullptr;
if (head == nullptr)
{
head = newNode;
}
else
{
Node *nodePtr = head;
while (nodePtr->next != nullptr)
{
nodePtr = nodePtr->next;
}
nodePtr->next = newNode;
}
}
code for deep copy
LL::LL(const LL& source)
{
head = nullptr;
Node *nodePtr = source.head;
while(nodePtr)
{
append(nodePtr->name,nodePtr->phoneNumber);
nodePtr = nodePtr->next;
}
}
main.cpp
#include <iostream>
#include "node.h"
using namespace std;
int main()
{
LL list;
list.append("jack","2");
list.append("jack2","1");
list.append("jack3","3");
list.append("jack4","4");
list.insertatBegin("notjack","0");
list.print();
list.searchByName("jack");
cout << "cloning------------------" <<endl;
LL list2(list);
//list.destroy();
//list2.append("jack","223");
list2.print();
if(list == list2)
{
cout << "same" <<endl;
}
else
{
cout << "not same" <<endl;
}
}
.h file
#ifndef NODE_H
#define NODE_H
#include <iostream>
using namespace std;
class Node
{
public:
string name; //data
string phoneNumber;
Node* next; //pointer to next
};
class LL
{
private:
Node* head; // list header
public:
LL();
~LL();
LL(const LL& source);
void append(string pName,string phone);
void insertatBegin(string pName,string phone);
void searchByName(string pName);
void print();
void destroy();
bool operator== (const LL& L1);
};
#endif
cpp file for class functions
bool LL::operator == (const LL &L1)
{
bool status = true;
Node *nodePtr = L1.head;
Node *nodePtr2 = head;
//cout << tmp.head <<endl;
while (nodePtr != nullptr)
{
if (nodePtr == nodePtr2)
{
nodePtr = nodePtr->next;
nodePtr2 = nodePtr2->next;
}
else
{
status = false;
}
}
return status;
}
I do not know what is your implementation of Copy Constructor if it is working fine then this should work.
bool LL::operator==(const LL& L1) const{
if (&L1==this){
return true;
}
else{
Node* current = L1.head;
Node* lhs = this->head;
while(current != nullptr){
if(current->name != lhs->name || current->phoneNumber != lhs->phoneNumber)
return false;
current = current->next;
lhs = lhs->next;
}
return true;
}}
I have compiled my code and it seemed to work correctly. But out of no-where I get the error (this->tail was nullptr). I have tried changing the creation of the new node. But nothing seems to work. I cannot tell where tail is being set to nullptr and messing up the code.
How would I go about fixing this problem? Is there any way to set tail to non-nullptr without ruining every other function? I am not too familiar with exception throwing, so if you could explain the situation it would help a lot.
#ifndef MYDLL_H
#define MYDLL_H
#include <iostream>
#include <new>
using namespace std;
class MyDLL
{
struct Node
{
int i;
Node* next;
Node* prev;
};
Node* head;
Node* tail;
public:
MyDLL();
~MyDLL();
void append(int);
void remove(int);
bool find(int) const;
void clear();
void print() const;
void reverse() const;
};
MyDLL::MyDLL()
{
head = nullptr;
tail = nullptr;
}
MyDLL::~MyDLL()
{
clear();
}
void MyDLL::append(int i)
{
Node *n = new Node{ i, nullptr, nullptr };
if (head = nullptr)
{
head = n;
tail = n;
}
else
{
n->prev = tail;
tail->next = n; **<--- This is where the exception thrown error is showing up**
tail = n;
}
}
void MyDLL::remove(int i)
{
Node* p = head;
Node* q = tail;
while (p != nullptr && p->i != i)
{
q = p;
p = p->next;
}
if (p = nullptr)
{
return;
}
if (q = nullptr)
{
head = p->next;
}
else
{
q->next = p->next;
}
if (p->next = 0)
{
tail = q;
}
else
{
p->next->prev = q;
}
delete(p);
}
bool MyDLL::find(int i) const
{
Node* p = tail;
while (p != nullptr)
{
if (p->i = i)
{
return (true);
}
p = p->prev;
}
return (false);
}
void MyDLL::clear()
{
while (tail != nullptr)
{
Node* p = tail;
tail = p->prev;
delete (p);
}
head = nullptr;
}
void MyDLL::print() const
{
Node* p = head;
while (p)
{
cout << p->i << "\t";
p = p->next;
}
cout << "\n";
}
void MyDLL::reverse() const
{
Node* p = tail;
while (p)
{
cout << p->i << "\t";
p = p->prev;
}
cout << "\n";
}
#endif
int main()
{
MyDLL list;
list.append(5);
list.append(6);
list.append(7);
list.append(8);
list.print();
list.reverse();
cout << system("pause");
}
This code is exactly why you want to use nullptr = tail instead of tail = nullptr. In particular, every time you "check" for tail to be a null pointer, you are assigning nullptr to tail, and then assign operator returns a value which gets then implicitly casted to a boolean value, giving you no errors. But the error is actually there. Replace the "=" operator with "==" when performing a comparison, unless you actually have a reason for assigning and checking the return value.
Please fix = with == in your code.
void MyDLL::append(int i)
{
Node *n = new Node{ i, nullptr, nullptr };
if (head == nullptr)
It is always recommended to do like the reverse comparison (nullptr == head)
I am trying to implement the a dot product calculation formula into the linked list implementation on my below code and I am having the below error:
request for member 'add_node' in 'B', which is of pointer type 'linked_list {aka node*}' (maybe you meant to use '->' ?)
How can I clear that and make working code? I don't want to use classes as well
#include <iostream>
#include <stdlib.h>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
typedef node* linked_list;
node *head = NULL;
node *tail = NULL;
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
int product=0;
while(A!=0 && B!=0)
{
if(A->index == B->index)
{
product = product + A->data * B->data;
A=A->next;
B=B->next;
}
else if(A->index < B->index)
{
A=A->next;
}
else
{
B=B->next;
}
}
return product;
return 0;
}
The error tells you what you need to know. linked_list is a pointer. You need to use the -> operator, not the dot operator.
Additionally, your node struct does not contain a method called add_node(). In fact it doesn't contain any methods at all.
#include <iostream>
using namespace std;
struct node
{
int data;
int index;
node *next;
};
class linked_list
{
private:
node *head,*tail;
public:
linked_list()
{
head = NULL;
tail = NULL;
}
void add_node(int i,int n)
{
node *tmp = new node;
tmp->index = i;
tmp->data = n;
tmp->next = NULL;
if(head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tail->next;
}
}
node* gethead()
{
return head;
}
};
void display(node *head)
{
while(head!=0)
{
cout << head->index <<" ," << head->data << endl;
display(head->next);
break;
}
}
int main()
{
linked_list A;
A.add_node(2,7);
A.add_node(4,5);
A.add_node(7,8);
A.add_node(9,4);
linked_list B;
B.add_node(3,5);
B.add_node(4,6);
B.add_node(9,5);
display(A.gethead());
display(B.gethead());
int product=0;
node *current_a = A.gethead();
node *current_b = B.gethead();
while(current_a != 0 && current_b!=0)
{
if(current_a->index == current_b->index)
{
product = product + current_a->data * current_b->data;
current_a=current_a->next;
current_b=current_b->next;
}
else if(current_a->index < current_b->index)
{
current_a=current_a->next;
}
else
{
current_b=current_b->next;
}
}
cout<<"\nDot Product : "<< product<<endl;
return 0;
}
enter code here
this is my lab and I work all of it. After long time of debugging, fixing errors, finally it can compile. But when it run, it didn't give me the correct answer. It just kept saying : did not find y (may be x was added) and it was 4 line with the same answer.
please look at my code and tell me why it didn't work.
Thanks a lot.
Here is my code:
LinkedList.h:
#ifndef _LINKED_LIST_
#define _LINKED_LIST_
#include <ostream>
class LinkedList
{
public:
LinkedList();
LinkedList(char ch);
LinkedList(const LinkedList& List);
~LinkedList();
void add(const char& ch);
bool find(char ch);
bool del(char ch);
friend std::ostream& operator<<(std::ostream& out, LinkedList& list);
private:
struct node
{
char item;
node * next;
};
node * head;
int size;
};
#endif // _LINKED_LIST_
Linkedlist.cpp
#include "linkedlist.h"
#include <iostream>
#include <fstream>
#include <cassert>
#include <cstring>
using namespace std;
LinkedList::LinkedList() : head(NULL)
{
}
LinkedList::LinkedList(char ch):head(NULL)
{
char currData;
currData = ch;
add(currData);
}
LinkedList::~LinkedList()
{
node * curr = head;
while(head)
{
curr = head->next;
delete head;
head = curr;
}
}
LinkedList::LinkedList(const LinkedList& List)
{
if(List.head == NULL)
head = NULL;
else
{
//copy first node
head = new node;
assert(head != NULL);
head->item = List.head->item;
//copy the rest of the list
node * destNode = head; //points to the last node in new list
node * srcNode = List.head->next; //points to node in aList
while(srcNode != NULL) //or while (srcNode)
{
destNode->next = new node;
assert(destNode->next != NULL); //check allocation
destNode = destNode->next;
destNode->item = srcNode->item;
srcNode = srcNode->next;
}
destNode->next = NULL;
}
}
ostream& operator<<(std::ostream& out, LinkedList& list)
{
while(list.head)
{
out << list.head->item << endl;
list.head = list.head->next;
}
return out;
}
void LinkedList::add(const char& ch)
{
node * prev = NULL;
node * curr = head;
while (curr != NULL && curr->item < ch)
{
prev = curr;
curr = curr->next;
}
if (curr && curr->item != ch)
{
node * newNode = new node;
newNode->item = ch;
newNode->next = NULL;
newNode->next = curr;
if (prev == NULL)
head = newNode;
else
prev->next = newNode;
size++;
}
}
bool LinkedList::del(char ch)
{
char a;
node * prev = NULL;
node * curr = head;
while (curr)
{
a = curr->item;
if ( a == ch)
{
if(!prev)
head = curr->next;
else
prev->next = curr->next;
delete curr;
size--;
return true;
}
prev = curr;
curr = curr->next;
}
return false;
}
bool LinkedList::find(char ch)
{
char a;
node * prev = NULL;
node * curr = head;
while (curr)
{
a = curr->item;
if ( a == ch)
{
return true;
}
prev = curr;
curr = curr->next;
}
return false;
}
app.cpp
#include <iostream>
#include "linkedlist.h"
using namespace std;
void find(LinkedList& list, char ch)
{
if (list.find(ch))
cout << "found ";
else
cout << "did not find ";
cout << ch << endl;
}
int main()
{
LinkedList list;
list.add('x');
list.add('y');
list.add('z');
cout << list;
find(list, 'y');
list.del('y');
cout << list;
find(list, 'y');
list.del('x');
cout << list;
find(list, 'y');
list.del('z');
cout << list;
find(list, 'y');
return 0;
}
Your add method doesn't work, if the item to insert goes at the end it is not inserted (because you are checking for curr == NULL before inserting). Since head is set to NULL when you create the list if(curr && ...) won't ever be true and no item will be inserted.