#include "node.h"
#include <iostream>
// List class
class List
{
node *head; // head is an object that stores the address of the first node
public:
// constructor that initializes every list to null
List()
{
head = NULL;
}
// prtototype of the list member functions
void Print();
void Insert(float sal, int en);
void Delete(float sal, int en);
};
//linklist.h above
#include "linklist.h"
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
/**
* Append a node to the linked list
*/
void List::Insert(float sal, int en)
{
// Create a new node
node* newNode = new node();
newNode->SetData(sal, en);
newNode->setNext(NULL);
// Create a temp pointer
node *tmp = head;
if ( tmp != NULL )
{
// Nodes already present in the list
// Parse to end of list
/*while ( tmp->Next() != NULL )
{
tmp = tmp->Next();
}*/
// Point the last node to the new node
tmp->setNext(head);
}
else
{
// First node in the list
head = newNode;
}
}
/**
* Delete a node from the list
*/
void List::Delete(float salary, int data)
{
// Create a temp pointer
node *tmp = head;
// No nodes
if ( tmp == NULL )
return;
// Last node of the list
if ( tmp->Next() == NULL )
{
delete tmp;
head = NULL;
}
else
{
// Parse thru the nodes
node *prev;
do
{
if ( tmp->Epnum() == data && tmp->Salary()== salary )
break;
prev = tmp;
tmp = tmp->Next();
} while ( tmp != NULL );
// Adjust the pointers
prev->setNext(tmp->Next());
// Delete the current node
delete tmp;
}
}
/**
* Print the contents of the list
*/
void List::Print()
{
// Temp pointer
node *tmp = head;
// No nodes
if ( tmp == NULL )
{
cout << "EMPTY" << endl;
return;
}
// One node in the list
if ( tmp->Next() == NULL )
{
cout << tmp->Salary() + tmp->Epnum();
cout << " --> ";
cout << "NULL" << endl;
}
else
{
// Parse and print the list
do
{
cout << tmp->Epnum();
cout << " --> ";
tmp = tmp->Next();
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
}
//linlist.cpp above
#include <iostream>
#include <cstdlib>
#include "linklist.h"
using namespace std;
void menu(List &);
int main()
{
// New list
List list;
menu(list);
return 0;
}
void menu(List &list)
{ char choice;
int item;
float salary;
do{
system("CLS"); // use #include <cstdlib>
cout << "\t\t\tMain Menu\n\n";
cout << "\tInsert{A}\n";
cout << "\tDelete\n";
cout << "\tPrint{P}\n";
cout << "\tExit\n";
cout << "\t\t What? ";cin >>choice;
choice = toupper(choice);
cin.ignore();
switch (choice)
{ case 'A':
cout << "Enter Employee numbers to insert and salary : "; cin >> item; cin>>salary;
list.Insert(salary, item);
cout << item<< " Inserted \n"; cin.get();
break;
/*case 'D':
cout << "Enter Item to Delete : "; cin >> item;
list.Delete(item);
cout << item<< " Deleted\n";cin.get();
break;*/
case 'P':
list.Print();cin.get();
break;
}
}while (choice != 'E');
}
//main.cpp above
//node.h
//#ifndef NODE_H
#define NODE_H
//node class
class node {
int epnum;
float salary;
node* next;
public:
node()
{} //null constructor
//stores argument passed in func.
void SetData(float _salary, int _epnum){
salary = _salary;
epnum = _epnum;
}
//stores in next the address of the next node
void setNext (node* anext){
next = anext;
}
//returns epnum stored
int Epnum(){
return epnum;
}
float Salary(){
return salary;}
//returns addres of next node
node* Next(){
return next;
}
};
//node.h above
I need to create a linked list that inserts a node at the front of the list as a program and of course print it out. I am unable to insert the node at the front of the list for some reason and I run into an infinte loop while trying to print it. It does something but I do not know exactly what. Please help.
In List::Insert, you have:
node *tmp = head;
followed by
tmp->next = head;
Hence, you have circular link in the object. Its next points to itself. This leads to infinite loop in the print function.
What you need is very simple:
void List::Insert(float sal, int en)
{
// Create a new node
node* newNode = new node();
newNode->SetData(sal, en);
newNode->setNext(head);
head = newNode;
}
In your insert method when you have 1 element already present tmp is set to head, then tmp->setNext(head); will create a reference to itself. This is the reason of infinite loop in your print method. Try the following insert code instead.
void List::Insert(float sal, int en)
{
// Create a new node
node* newNode = new node();
newNode->SetData(sal, en);
newNode->setNext(head);
head = newNode;
}
I would also note that in you print method there is no corner case for the list with 1 element. Your loop will perfectly handle this case. You will get the same result if you omit One node in the list branch.
void List::Print()
{
// Temp pointer
node *tmp = head;
// No nodes
if ( tmp == NULL )
{
cout << "EMPTY" << endl;
return;
}
// Parse and print the list
do
{
cout << tmp->Epnum();
cout << " --> ";
tmp = tmp->Next();
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
void List::Insert(float sal, int en)
{
// Create a new node
node* newNode = new node();
newNode->SetData(sal, en);
newNode->setNext(NULL);
//set the newNode next to point to head
newNode->setNext(head);
//set the new head as the newNode
head = newNode;
// Create a temp pointer
//node *tmp = head;
/*if ( tmp != NULL )
{
// Nodes already present in the list
// Parse to end of list
/*while ( tmp->Next() != NULL )
{
tmp = tmp->Next();
}
// Point the last node to the new node
tmp->setNext(head);
}
else
{
// First node in the list
head = newNode;
}*/
}
/**
* Delete a node from the list
*/
void List::Delete(float salary, int data)
{
// Create a temp pointer
node *tmp = head;
// No nodes
if ( tmp == NULL )
return;
// Last node of the list
if ( tmp->Next() == NULL )
{
delete tmp;
head = NULL;
}
else
{
// Parse thru the nodes
node *prev;
do
{
if ( tmp->Epnum() == data && tmp->Salary()== salary )
break;
prev = tmp;
tmp = tmp->Next();
} while ( tmp != NULL );
// Adjust the pointers
prev->setNext(tmp->Next());
// Delete the current node
delete tmp;
}
}
/**
* Print the contents of the list
*/
void List::Print()
{
// Temp pointer
node *tmp = head;
// No nodes
if ( tmp == NULL )
{
cout << "EMPTY" << endl;
return;
}
// One node in the list
if ( tmp->Next() == NULL )
{
cout << tmp->Salary() + tmp->Epnum();
cout << " --> ";
cout << "NULL" << endl;
}
else
{
// Parse and print the list
do
{
cout << tmp->Epnum();
cout << " --> ";
tmp = tmp->Next();
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
}
nvm i was tired when i was writting this code and just realized what I did wrong.
Related
I'm working on an assignment for my college class, and I'm struggling to figure out why code for my push_front() function works without fail, but my push_back() always gives:
"Exception thrown: read access violation. st was nullptr."
struct NodeDate
{
int day, month, year; //Structure's data
struct NodeDate* nextNode; //Pointer to point to next node
}*start; //Not sure why we do this, but all examples contain it
class LinkedListDate
{
public:
//Prototype of member functions
NodeDate* create_node(NodeDate);
void push_front();
void pop_front();
void remove_front();
void search();
void display();
LinkedListDate();
void push_back();
void remove_back();
void pop_back();
};
LinkedListDate::LinkedListDate()
{
start = NULL; //Our first created pointer will be set to NULL
}
NodeDate* LinkedListDate::create_node(struct NodeDate newDate) //Function that creates a new node and returns said node
{
struct NodeDate* tempNode, *s;
tempNode = new(struct NodeDate); //Reserving memory for our temp node
if (tempNode == NULL) //If the node is empty
{
std::cout << "Memory not allocated " << std::endl;
return 0;
}
else //Otherwise assign parameter node value to temporary node
{
tempNode->day = newDate.day;
tempNode->month = newDate.month;
tempNode->year = newDate.year;
tempNode->nextNode = NULL; //Remember these are all values contained within the date struct
return tempNode; //Return the node
}
}
void LinkedListDate::push_front() //Function that will insert a node at the start of our linkedlist
{
struct NodeDate* tempNode, *st, newNode;
std::cout << "Enter the day: ";
std::cin >> newNode.day;
std::cout << "Enter the month: ";
std::cin >> newNode.month;
std::cout << "Enter the year: ";
std::cin >> newNode.year;
tempNode = create_node(newNode); //Creating a new node for date with the create_node function
if (start == NULL) //Checks if the starting (Head) node is NULL then first node to insert
{
start = tempNode; //Start node points to our temporary node
start->nextNode = NULL; //Assign null to start->next
}
else //Otherwise nodes are already available in the list
{
st = start; //Assign start to st
start = tempNode; //Start points to temporary node
start->nextNode = st; //Start next point to st
}
std::cout << "Element Inserted at beginning" << std::endl;
}
void LinkedListDate::push_back() //Function to insert a new node at the end of the linkedlist
{
struct NodeDate* tempNode, *st, newNode;
std::cout << "Enter the day: ";
std::cin >> newNode.day;
std::cout << "Enter the month: ";
std::cin >> newNode.month;
std::cout << "Enter the year: ";
std::cin >> newNode.year;
tempNode = create_node(newNode); //Creating a new node for date with the create_node function
st = start;
while (st->nextNode != NULL) //Move til we reach end of the list
{
st = st->nextNode; //Move to the next node
}
tempNode->nextNode = NULL; //Assign null to temporary node next
st->nextNode = tempNode; //st next points to temporary node
std::cout << "Element Inserted at last" << std::endl;
}
Again, push_front() works, but push_back() does not work (The program runs, but after inputting the date for the first node I get the exception.
I've been trying a lot of things, but I can't seem to figure out what exactly I'm doing wrong.
struct NodeDate
{
//...
}*start;
is the same is
struct NodeDate
{
//...
};
NodeDate *start;
push_back will fail when the list is empty (i.e. start is null).
void LinkedListDate::push_back()
{
//...
tempNode = create_node(newNode);
tempNode->nextNode = nullptr;
if(start == nullptr)
{
start = tempNode;
}
else
{
st = start;
while (st->nextNode != nullptr) //Move til we reach end of the list
{
st = st->nextNode; //Move to the next node
}
st->nextNode = tempNode;
}
std::cout << "Element Inserted at last" << std::endl;
}
We are suppose to enter a string, and then find where the string is in the linked list and remove that node
when i insert to the front of the list, so i enter data values a, b, c , d, when i print it it comes up as d,c,b,a. Now i insert to the rear of it, entering f and g, and the list now looks, d,c,b,a,f,g. I want to remove f but it just use the remove function it does not and still output the same list
using namespace std;
struct node {
string data;
node* next;
};
node* addFront(node* s);
node* addRear(node* s);
void remove(node* head, string abc);
void print(node* head);
int main() {
node* head = NULL;
cout << "Enter 5 data strings\n";
cout << "This will be inserted from the back\n";
for (int i = 0; i < 5; i++) {
head = addFront(head);
}
print(head);
cout << "Enter 3 strings and this will be inserted from the back of the orignal string\n";
for (int i = 0; i < 3; i++) {
head = addRear(head);
}
print(head);
cout << "Removing the head node\n";
string n;
cout << "Enter a string to remove\n";
cin >> n;
remove(head, n);
print(head);
}
node* addFront(node* s)
{
node* person = new node;
cin >> person->data;
person->next = s;
s = person;
return s;
}
node *addRear(node*s ) {
node* person = new node;
cin >> person->data;
person->next = NULL;
if (s == NULL) {
return person;
}
else {
node* last = s;
while (last->next != NULL) {
last = last->next;
}
last->next = person;
}
return s;
}
void remove(node* head, string a) {
node* previous = NULL;
node* current = head;
if (current == NULL) {
cout << "Value cannot be found\n";
return;
}
else {
while (previous != NULL) {
if (current->data == a) {
previous->next = current->next;
delete current;
break;
}
current = current->next;
}
}
}
void print(node * head)
{
node* temp = head;
while (temp != NULL) // don't access ->next
{
cout << temp->data << " ";
temp = temp->next;
}
cout << endl;
}
In remove function, previous is most certainly NULL when you hit that while loop.
Perhaps consider a do-while loop instead (with better handling of previous).
You may be better off handling the first node in a different manner since the holder of its previous is essentially the root pointer.
So i am trying to use double pointers to create insert function and then print the linked list.
I managed to do it with single pointers but this double pointer is driving me insane.
#include <iostream>
#include <string>
using namespace std;
class Node {
public:
string name;
int ID;
int marks[10];
Node *next;
};
void printOptions() {
cout << endl;
cout << "1.Insert New Node" << endl;
cout << "2.Print List" << endl;
cout << "3.Exit" << endl;
}
void insertAtBack(string inputName, Node **headref) {
Node **currentNodeRef;
currentNodeRef = headref;
while ((*currentNodeRef)->next != NULL) {
(*currentNodeRef) = (*currentNodeRef)->next;
}
(*currentNodeRef)->next = new Node();
(*currentNodeRef)->next->name = inputName;
(*currentNodeRef)->next->next = NULL;
}
void printList(Node *head) {
Node *indexNode;
indexNode = head;
while (indexNode != NULL) {
cout << (indexNode)->name << endl;
(indexNode) = (indexNode)->next;
}
}
int main() {
cout << "This implements a linked list" << endl;
int option;
bool infinite = true;
Node *head = NULL;
string testName;
while (infinite == true) {
printOptions();
std::cin >> option;
switch (option) {
case 1:
cout << "Enter student name" << endl;
std::cin >> testName;
if (head == NULL) {
head = new Node();
head->name = testName;
}
else {
insertAtBack(testName, &head);
}
break;
case 2:
printList(head);
break;
case 3:
exit(1);
break;
default:
exit(1);
break;
}
}
return 0;
}
So there is no compilation error or seg fault but instead the code runs it takes in 2 values and prints them fine. when the another value is typed inserted it only prints 2 values no more.
I think the print function is good because it worked previously with single pointer but i am not 100% sure.
I think the problem is in the insert function but i am not sire where.
void insertAtBack(string inputName, Node **headref) {
Node **currentNodeRef;
currentNodeRef = headref;
...
Node **currentNodeRef = headref; is an error. Remember you are passing the address of a pointer. You mean to write:
Node *currentNodeRef = *headref;
And change the function like so:
void insertAtBack(string inputName, Node **head)
{
Node *tail = *head;
while(tail->next != NULL)
tail = tail->next;
tail->next = new Node();
tail->next->name = inputName;
tail->next->next = NULL;
}
Also don't forget to initialize head->next = nullptr;
if (head == NULL) {
head = new Node();
head->name = testName;
head->next = nullptr; <--- add
}
It is better however if insertAtBack is prepared to handle head when head is NULL. The whole reason you pass Node **head is because you want a reference to the pointer so you can initialize it. So you can modify the code as:
void insertAtBack(string inputName, Node **head)
{
Node *new_node = new Node();
new_node->name = inputName;
new_node->next = nullptr;
if(*head)
{
Node *tail = *head;
while(tail->next)
tail = tail->next;
tail->next = new_node;
}
else
{
*head = new_node;
}
}
void printList(Node *head)
{
Node *node = head;
while(node)
{
cout << node->name << endl;
node = node->next;
}
}
int main()
{
cout << "This implements a linked list" << endl;
Node *head = NULL;
string testName;
while(true)
{
printOptions();
int option;
std::cin >> option;
switch(option)
{
case 1:
cout << "Enter student name" << endl;
std::cin >> testName;
insertAtBack(testName, &head);
break;
case 2: printList(head); break;
case 3: exit(1); break;
default: exit(1); break;
}
}
return 0;
}
I have the following code but it gives an error on the line - e = list.first();(towards the end of the code). It says that it cannot convert Node to char can someone tell me how to get return the first value from the linked list in the variable e.
Thanks for all the help:)
//
// main.cpp
// cprogram1
//
#include <iostream>
using namespace std;
class Node {
char data;
Node* next;
public:
Node() {};
void SetData(int aData) { data = aData; };
void SetNext(Node* aNext) { next = aNext; };
char Data() { return data; };
Node* Next() { return next; };
};
// List class
class List {
Node *head;
public:
List() { head = NULL; };
void Print();
void Append(int data);
void Delete(int data);
Node * First() const;
};
/**
* Print the contents of the list
*/
void List::Print() {
// Temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL ) {
cout << "EMPTY" << endl;
return;
}
// One node in the list
if ( tmp->Next() == NULL ) {
cout << tmp->Data();
cout << " --> ";
cout << "NULL" << endl;
}
else {
// Parse and print the list
do {
cout << tmp->Data();
cout << " --> ";
tmp = tmp->Next();
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
}
/**
* Append a node to the linked list
*/
void List::Append(int data) {
// Create a new node
Node* newNode = new Node();
newNode->SetData(data);
newNode->SetNext(NULL);
// Create a temp pointer
Node *tmp = head;
if ( tmp != NULL ) {
// Nodes already present in the list
// Parse to end of list
while ( tmp->Next() != NULL ) {
tmp = tmp->Next();
}
// Point the last node to the new node
tmp->SetNext(newNode);
}
else {
// First node in the list
head = newNode;
}
}
/**
* Delete a node from the list
*/
void List::Delete(int data) {
// Create a temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL )
return;
// Last node of the list
if ( tmp->Next() == NULL ) {
delete tmp;
head = NULL;
}
else {
// Parse thru the nodes
Node *prev;
do {
if ( tmp->Data() == data ) break;
prev = tmp;
tmp = tmp->Next();
} while ( tmp != NULL );
// Adjust the pointers
prev->SetNext(tmp->Next());
// Delete the current node
delete tmp;
}
}
Node * List::First() const {
Node *tmp = head;
return head;
}
int main ()
{
char c;
int t = 0;
char e;
List list;
while(t==0)
{
cout << "Please enter your command";
cin >> c;
if(c=='c')
{
cout << "You will need to enter 6 letters, one after the other";
cout << "Please enter the first letter";
cin >> e;
list.Append(e);
cout << "Please enter the second letter";
cin >> e;
list.Append(e);
cout << "Please enter the third letter";
cin >> e;
list.Append(e);
cout << "Please enter the fourth letter";
cin >> e;
list.Append(e);
cout << "Please enter the fifth letter";
cin >> e;
list.Append(e);
cout << "Please enter the sixth letter";
cin >> e;
list.Append(e);
list.Print();
list.Delete('b');
list.Print();
e = list.First();
}
}
}
Lets take a look to your program : tested here :
#include <iostream>
using namespace std;
class Node {
char data;
Node* next;
public:
Node() {};
void SetData(int aData) { data = aData; };
void SetNext(Node* aNext) { next = aNext; };
char Data() { return data; };
Node* Next() { return next; };
};
// List class
class List {
Node *head;
public:
List() { head = NULL; };
void Print();
void Append(int data);
void Delete(int data);
Node * First() const;
};
/**
* Print the contents of the list
*/
void List::Print() {
// Temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL ) {
cout << "EMPTY" << endl;
return;
}
// One node in the list
if ( tmp->Next() == NULL ) {
cout << tmp->Data();
cout << " --> ";
cout << "NULL" << endl;
}
else {
// Parse and print the list
do {
cout << tmp->Data();
cout << " --> ";
tmp = tmp->Next();
}
while ( tmp != NULL );
cout << "NULL" << endl;
}
}
/**
* Append a node to the linked list
*/
void List::Append(int data) {
// Create a new node
Node* newNode = new Node();
newNode->SetData(data);
newNode->SetNext(NULL);
// Create a temp pointer
Node *tmp = head;
if ( tmp != NULL ) {
// Nodes already present in the list
// Parse to end of list
while ( tmp->Next() != NULL ) {
tmp = tmp->Next();
}
// Point the last node to the new node
tmp->SetNext(newNode);
}
else {
// First node in the list
head = newNode;
}
}
/**
* Delete a node from the list
*/
void List::Delete(int data) {
// Create a temp pointer
Node *tmp = head;
// No nodes
if ( tmp == NULL )
return;
// Last node of the list
if ( tmp->Next() == NULL ) {
delete tmp;
head = NULL;
}
else {
// Parse thru the nodes
Node *prev;
do {
if ( tmp->Data() == data ) break;
prev = tmp;
tmp = tmp->Next();
} while ( tmp != NULL );
// Adjust the pointers
prev->SetNext(tmp->Next());
// Delete the current node
delete tmp;
}
}
Node * List::First() const {
Node *tmp = head;
return head;
}
int main ()
{
char c;
int t = 0;
char e;
List list;
while(t==0)
{
cout << "Please enter your command";
c = 'c';
//cin >> c;
if(c=='c')
{
cout << "You will need to enter 6 letters, one after the other";
cout << "Please enter the first letter";
list.Append('e');
cout << "Please enter the second letter";
//cin >> e;
list.Append('a');
cout << "Please enter the third letter";
//cin >> e;
list.Append('b');
cout << "Please enter the fourth letter";
//cin >> e;
list.Append('f');
cout << "Please enter the fifth letter";
//cin >> e;
list.Append('h');
cout << "Please enter the sixth letter";
//cin >> e;
list.Append(e);
list.Print();
list.Delete('b');
list.Print();
e = list.First()->Data();
t=1;
}
}
}
As you can see, e = list.First() return a pointer to a Node, not a char. You have implemented a function that return a char which is Data(). Thus, you should use e = list.First()->Data();.
Also, your loop is infinite because t is always 0. I just put t=1 to stop your loop and see the result. (if you use this code, don't forget to uncomment the cin and remove c = 'c')
Hope that helps you.
When I run your code I get the error:
main.cpp: error: assigning to 'char' from incompatible type 'Node *'
e = list.First();
^ ~~~~~~~~~~~~
which I think explains it.
Try this:
e = list.First()->Data();
I just implemented a Destructor and I am getting an “Access violation reading location”. I beleive the problem is in my while loop but just can't figure it out.
Below is my code. If needing to reference any other part of my List Class please let me know.
Thanks!
List::List():first(NULL), last(NULL), nodeListTotal(0)
{
}
List::~List()
{
Node* currentNode = first;
while( currentNode != 0 )
{
Node* temp = currentNode->getNext();
delete currentNode;
currentNode = temp;
}
first = 0;
}
Here is my entire List class. I have made the changes recommended, removed the first = 0; and change 0 to nullptr
#include "Node.h"
#include <string>
using namespace std;
class List
{
private:
int nodeListTotal;
Node* first;
Node* last;
public:
//Constructor
List();
//Destructor
~List();
//Copy-Constructor
//List(const List& theList);
//////Overloading Assignment Operator
//List& operator=(const List& L);
void push_back(Node*);
void push_front(Node*);
Node* pop_back();
Node* pop_front();
Node* getFirst() const;
Node* getLast() const;
int getListLength() const;
};
List::List():first(NULL), last(NULL), nodeListTotal(0)
{
}
// Destructor
List::~List()
{
Node* currentNode = first;
while( currentNode != nullptr )
{
Node* temp = currentNode->getNext();
delete currentNode;
currentNode = temp;
}
}
// Copy-Constructor
//List::List(const List& theList)
//{
// Node * tempPtr = new Node;
// tempPtr = theList.first;
// List(tempPtr);
//
// while (tempPtr != NULL)
// {
// Node * copyNode = new Node;
// copyNode = tempPtr;
// tempPtr = tempPtr->getNext();
// nodeListTotal++;
// }
//}
// Overloading Assignemnt Operator
//List& List::operator=(const List& L)
//{
// List* overList;
// Node* temp = L.first;
//
// while( temp != NULL ) {
// overList->getLast();
// temp = temp -> getNext();
//
// return *this;
//}
void List::push_back(Node* newNode)
{
Node* temp = last;
if (temp)
temp->setNext(newNode);
else
first = newNode;
last = newNode;
nodeListTotal++;
}
void List::push_front(Node* newNode)
{
Node* temp = getFirst();
newNode->setNext(temp);
first = newNode;
nodeListTotal++;
if (!temp)
last = first;
}
Node* List::pop_back()
{
Node* old = last;
if (first == last)
{
first = 0;
last = 0;
}
else
{
Node* temp = first;
for (int i = 0; i < (nodeListTotal - 1); i++)
{
temp = temp->getNext();
}
temp->setNext(NULL);
last = temp;
}
nodeListTotal--;
return old;
}
Node* List::pop_front()
{
Node* temp = getFirst();
first = temp->getNext();
if (!first)
last = 0;
nodeListTotal--;
return temp;
}
Node* List::getFirst() const
{
return first;
}
Node* List::getLast() const
{
return last;
}
int List::getListLength() const
{
return nodeListTotal;
}
Node.h
#include <string>
using namespace std;
class Node
{
private:
string dataItem;
string dataUnit;
int unitTotal;
Node* next;
public:
//Constructor
Node();
Node(int, string, string);
string getDescription( )const;
void setDescription(string);
string getQuantityName()const;
void setQuantityName(string);
int getQuantityNumber()const;
void setQuantityNumber(int);
Node* getNext( )const;
void setNext(Node*);
};
Node::Node(void):dataItem("None"), dataUnit("None"), unitTotal(0), next(NULL)
{
}
Node::Node(int q, string i, string u):dataItem(i), dataUnit(u), unitTotal(q), next(NULL)
{
}
string Node::getDescription( ) const
{
return dataItem;
}
void Node::setDescription(string iSetter)
{
dataItem = iSetter;
}
string Node::getQuantityName() const
{
return dataUnit;
}
void Node::setQuantityName(string uSetter)
{
dataUnit = uSetter;
}
int Node::getQuantityNumber() const
{
return unitTotal;
}
void Node::setQuantityNumber(int tSetter)
{
unitTotal = tSetter;
}
Node* Node::getNext() const
{
return next;
}
void Node::setNext(Node* nSetter)
{
next = nSetter;
}
Driver.cpp
int main( )
{
//===============================================
// PART ONE
//===============================================
cout << "\nPart I: push_front and pop_front\n";
cout << "\n----------------------------------\n";
List groceries;
// test push_back function
groceries.push_front(new Node(1, "gallon", "milk") );
groceries.push_front(new Node(2, "loaves", "bread") );
groceries.push_front(new Node(1, "dozen", "eggs" ) );
groceries.push_front(new Node(1, "package", "bacon") );
cout << "\nThe original nodes in the List:\n";
printList(groceries);
cout << "\n----------------------------------\n";
// test push_front function
cout << "\nAdding to the front of the List:\n";
cout << "\n----------------------------------\n";
groceries.push_front(new Node(2, "lbs", "hamburger") );
groceries.push_front(new Node(1, "dozen", "hamburger buns") );
printList(groceries);
cout << "\n----------------------------------\n";
// test pop-front
cout << "\nRemoving the first node from the list.\n";
cout << "\n----------------------------------\n";
Node* item = groceries.pop_front( );
cout << "\nPopped " << item->getDescription( ) << " from the list.\n\n";
printList(groceries);
if (item != NULL)
delete item;
// ===============================================
// PART TWO: Uncomment this block to test part two
// ===============================================
cout << "\n----------------------------------\n";
cout << "\nPart Two: Push_back and pop_back";
// test push_back
groceries.push_back(new Node(2, "cans", "orange juice") );
groceries.push_back(new Node(1, "lb", "swiss cheese") );
cout << "\nAdding two nodes at the end\n";
cout << "\n----------------------------------\n";
printList(groceries);
// test pop-back
cout << "\n----------------------------------\n";
cout << "\nRemove last node from the list\n";
cout << "\n----------------------------------\n";
item = groceries.pop_back( );
cout << "\nPopped " << item->getDescription( ) << " from the list.\n\n";
printList(groceries);
if (item != NULL)
delete item;
// ============================================
// end of part two
// ============================================
// ================================================
// PART THREE: uncomment this block to test part three
// ================================================
/*
// create a second list to test assignment
cout << "\n\n--------------extra credit------------------\n";
cout << "\n\n overloaded assignment operator\n";
cout << "The hardware list ...\n";
cout << "\n-------------------------------------------\n";
List hardware;
hardware.push_back(new Node(2, "lbs", "nails") );
hardware.push_back( new Node(3, "gals", "white paint") );
hardware.push_back(new Node(1, "piece", "plywood") );
printList(hardware);
hardware = groceries;
cout << "\n-------------------------------------------\n";
cout << "\nafter assignment";
cout << "\n-------------------------------------------\n";
printList(hardware);
cout << "\n-------------------------------------------\n";
cout << "\nTest the copy constructor\n";
cout << "\n-------------------------------------------\n";
printFirstNode(hardware);
// ==============================================
// end of part 3
// ==============================================
*/
cout << "\n-------------------------------------------\n";
cout << "\nEnd of Test";
cout << "\n-------------------------------------------\n";
system("PAUSE");
return 0;
}
Looks like pop back does not remove last node from the list, but returns it. Then the node is deleted and in list's destructor you try to delete it second time.
The push_back() method could be your culprit, coupled with the failure to initialize Node:next to zero. If only one node is added to the list using push_back then the value of that node's next member would be unknown and in the destructor an attempt to delete a second node referring to a random memory location would cause the access error.
Either ensure that the nodes values are initialized, or ensure that node.next is set explicitly in push_back() if it's the first node added to the list.
Something to note on pop_back() and pop_front().
Calling pop_back() on an empty list would still decrement nodeListTotal.
Calling pop_front() on an empty list would actually cause an access violation trying to access address 0.
The below deletion of node is causing the problem while cleaning up in the destructor.
if (item != NULL)
delete item;
When you do the pop_back you're deleting that(last) node in main(), but what happens to the node which is before that? it was pointing to the one which you deleted and is not set to NULL.
So, in the destructor when you start deleting the nodes you're checking for the NULL value of the nodes. All goes fine but now for the last one next wasn't set to NULL, instead it is still pointing to the one which you just deleted. Hence, tries to free the node which is already freed.
Then your code crashes.
Set the previous node's next to NULL whenever you're freeing the successive node.