I am trying to get a linked-list class-based queue that holds objects of type "Student", but I've been trying for two days to get this thing to work. Now I am seeing errors of exceptions at the copy constructor of the "Student" class and the return of the dequeue function, and am at a complete loss since I don't even know what that means.
My main issue, from what I can tell, is when I try to assign the return of the dequeue to an object, there is an issue with the fact that I'm using the standard = operator and not a custom operator= for the class. Then again, I am relatively new to classes so I don't know if this is actually the issue.
This is the main code that uses all my files:
#include <iostream>
#include <fstream>
#include <string>
#include "Student.h"
#include "Queue.h"
int main(void)
{
char TempFName[15], TempSName[20];
long Tid_num;
int Tage;
float Tgpa;
Student Student1, StudentA;
queue q1;
int no, temp;
ifstream ip("input.txt");
// modify for your location
ip >> no; /* read in the number of Students */
for (temp = 0; temp < no; temp++)
{
/* read in the Student data in file format */
ip >> TempFName;
Student1.assignFName(TempFName);
ip >> TempSName;
Student1.assignSName(TempSName);
ip >> Tid_num;
Student1.assignId(Tid_num);
ip >> Tage;
Student1.assignAge(Tage);
ip >> Tgpa;
Student1.assignGpa(Tgpa);
q1.enqueue(Student1);
}
ip.close();
queue q2(q1);
q2.enqueue(StudentA);
q1.enqueue(StudentA);
cout << "details for queue 2 are as follows" << endl;
for (temp = 0; temp < no + 1; temp++)
{
Student1 = q2.dequeue();
Student1.print();
}
cout << "There are " << Student1.getNum() << " Student objects in existence";
return 0;
}
My files are:
Student.cpp:
#include <iostream> // need for cout, etc
#include "Student.h"
using namespace std;
Student::Student(const Student& s)
{
firstname = s.firstname;
surname = s.surname;
id_num = s.id_num;
age = s.age;
gpa = s.gpa;
count++;
}
Student::~Student() { count--; }
void Student::assignFName(string tempFName)
{
firstname = tempFName;
}
void Student::assignSName(string tempSName) { surname = tempSName; }
void Student::assignId(long Tid_num) { id_num = Tid_num; }
void Student::assignAge(int Tage) { age = Tage; }
void Student::assignGpa(float Tgpa) { gpa = Tgpa; }
string Student::getSName() { return surname; }
long Student::getId_num() { return id_num; }
int Student::getAge() { return age; }
float Student::getGpa() { return gpa; }
int Student::getNum() { return count; }
void Student::print() const
{
cout << firstname << " " << surname << " " << id_num << " " << age << " ";
cout << gpa << endl; // could do on same line, but do on next line just so can see that can be multiple lines, etc
}
int Student::count = 0;
Student.h:
#pragma once
//Module.h
#ifndef STD_H
#define STD_H
#include <string>
using namespace std;
class Student
{
public:
// just include one constructor definition here to show how it is written if do inline
Student(string fn = "nofirstname", string sn = "nosurname", long i = 0000, int a = 0, float s = 0)
:firstname(fn), surname(sn), id_num(i), age(a), gpa(s) {
count++;
}
Student(const Student& s);
~Student();
void assignFName(string tempFName);
void assignSName(string tempSName);
void assignId(long Tid_num);
void assignAge(int Tage);
void assignGpa(float Tgpa);
string getFName() { return firstname; } // just include one method here to show how it is written if do inline
string getSName();
long getId_num();
int getAge();
float getGpa();
void print() const;
static int getNum();
private:
string firstname, surname;
long id_num;
int age;
float gpa;
static int count;
};
#endif
queue.cpp:
#include "Queue.h"
#include "Student.h"
#include <iostream>
#include <stdlib.h>
void queue::enqueue(Student value) {
QueueNode* temp = new QueueNode(value); //allocating memory for the newly created node, with a value passed into it
if (tail == NULL) { //If there is no tail (i.e. only 1 block in the queue)...
head = tail = temp; //The tail and head are now the one block
return; //
} //
tail->next = temp; //The next address of the tail is made to equal the temporary node
tail = temp; //The tail becomes the temporary node
delete temp;
}
Student queue::dequeue() {
Student a;
if (head == tail) {//if only one node is there
head = tail = NULL;
} else {
head = head->next;
}
if (head == NULL) {
exit(1);
}
a = head->value;
return a;
//Student a;
//QueueNode* temp = head; //store the current head node of the queue
//delete (temp);
//if (head != NULL) {
// head = head->next;
//
//} else {
// tail = NULL;
// //return a;
//}
//a = head->value;
//return a;
}
void queue::printQueue() {
int count = 1; //initiazling counter variable as 1 so that the counter does not start at 0
while (head != NULL) //while the are still blocks in the queue
{
//cout << "\n\tBlock number " << count << " pushed: " << ; //print the block that was just inserted and what position it is at
head->value.print();
head = head->next; //equate the node to the next address
count++; //increment the counter
}
}
queue::~queue() {
head = tail = NULL;
}
queue::queue(const queue& q) {
QueueNode* hold = q.head;
QueueNode* temp, * oldtemp;
if (hold == q.tail)
{
temp = new QueueNode;
head = temp;
tail = temp;
}
else
{
temp = new QueueNode;
head = temp;
while (hold != q.tail)
{
// get the value at the node looking at on queue 'r' list
temp->value = hold->value;
// move to the next entry on 'r' list
hold = hold->next;
oldtemp = temp;
temp = new QueueNode;
oldtemp->next = temp;
}
tail = temp;
}
}
queue::queue() {
head = tail = NULL;
}
//queue::sizeOfQueue() { //function to return the number of nodes in the queue
// //takes in the pointer to the queue so that the function knows which queu to get the size of
// int size = 0; //intialize size integer to be returned
// while (node != NULL) { //for as long as a NULL node is not reached
// node = node->next; //equate the node to the next address
// size++; //increment the size integer
// } //eventually the node will reach the end of the queue where the next address is NULL (because there are no other nodes)
// return size; //return the integer for the size
//}
queue.h:
#pragma once
#include "Student.h"
#include "Node.h"
class queue {
public:
queue();
queue(const queue& q);
~queue();
void enqueue(Student value);
Student dequeue();
void printQueue();
private:
QueueNode* head;
QueueNode* tail;
};
Node.cpp:
#include "Queue.h"
#include "Node.h"
#include "Student.h"
#include <iostream>
QueueNode::QueueNode() {
value = Student();
next = NULL;
}
QueueNode::QueueNode(Student val) {
value = val;
next = NULL;
}
QueueNode::~QueueNode() {
value.~Student();
next = NULL;
}
Node.h:
#pragma once
#include "Student.h"
class QueueNode {
friend void enqueue(Student value);
friend void dequeue();
friend void printQueue();
public:
QueueNode* next; //PUBLIC VARIABLE
Student value;
QueueNode();
QueueNode(Student val);
~QueueNode();
private:
};
The input file that gets the details for the "Student" objects that go in the queue:
3
joe bloggs 40001 24 2.1
mary doe 40002 19 3.9
john boyd 40003 18 1
Related
my problem is it's Process returned -1073741819. What shall i do to compile it faster?
#include "Queue.h"
#include <iostream>
Queue::Queue()
{
topPtr = NULL;
tailPtr = NULL;
}
bool Queue::isEmpty()
{
if(topPtr == NULL && tailPtr == NULL)
return true;
else
return false;
}
void Queue::enqueue(int data)
{
Node *newNodePtr = new Node;
newNodePtr->data = data;
if(topPtr == NULL)
{
topPtr = tailPtr = newNodePtr;
tailPtr->nextPtr = NULL;
}
else
{
tailPtr->nextPtr = newNodePtr;
tailPtr = newNodePtr;
tailPtr->nextPtr = NULL;
}
}
int Queue::dequeue()
{
if (isEmpty())
{
cout << "empty" <<endl;
}
else
{
int dataToReturn = topPtr->data;
Node *nodeToDeletePtr = topPtr;
dataToReturn = nodeToDeletePtr->nextPtr;
topPtr = topPtr->nextPtr;
delete nodeToDeletePtr;
return dataToReturn;
}
}
#ifndef QUEUE_H
#define QUEUE_H
struct Node
{
int data;
Node *nextPtr;
};
class Queue
{
public:
Queue();
void enqueue(int data);
int dequeue();
bool isEmpty();
private:
Node *topPtr;
Node *tailPtr;
};
#endif
#include <iostream>
#include <string.h>
#include <cstdlib>
#include "Queue.h"
using namespace std;
int main(int argc, char const *argv[])
{
Queue integers;
string seriesIntegers;
cout << "Enter integers: ";
getline(cin, seriesIntegers);
char *seriesIntegersCStr = new char[seriesIntegers.length() + 1];
strcpy(seriesIntegersCStr, seriesIntegers.c_str());
char *tokens = strtok(seriesIntegersCStr, " ");
while(tokens != NULL)
{
integers.enqueue(atoi(tokens));
tokens = strtok(NULL, " ");
}
while(!integers.isEmpty())
{
cout << " " << integers.dequeue() << "\n";
}
}
Among the things wrong:
You never reset tailPtr to null during a dequeue operation that emptied the queue.
Due to the first item, your isEmpty member was incorrectly reporting the queue still had data because one of the two conditions (tailPtr == nullptr) was not true, and therefore the queue wasn't "empty" even though it was.
Due to both of the items above, your while-loop in main ran off the end of the queue.
Your dequeue operation has a major control path that returns no value, though you promised in your declaration of returns-int that it would. At a minimum this should throw an exception; ideally it should not be allowed in the first place.
Queue should self-clean on destruction rather than leaking the node chain in a non-empty state.
As a course of adding a custom destructor to clean dynamic content, Queue should be rule-of-three compliant by either defining proper operations for copy-ctor and assignment operators, or specifying them as deleted (as I did below)
Fixing all of that, and a few other modifications, including entering the real world of modern C++ to utilize a string stream to read the integers rather than strtok and leaked memory as you were before, see the code below:
#include <iostream>
#include <sstream>
#include <string>
struct Node
{
int data;
Node *nextPtr;
Node(int val, Node *next = nullptr)
: data(val)
, nextPtr(next)
{
}
};
class Queue
{
public:
Queue();
virtual ~Queue();
Queue(const Queue&) = delete;
Queue& operator =(const Queue&) = delete;
void enqueue(int data);
int dequeue();
bool isEmpty() const;
private:
Node *topPtr;
Node *tailPtr;
};
Queue::Queue()
: topPtr(nullptr)
, tailPtr(nullptr)
{
}
Queue::~Queue()
{
while (topPtr)
dequeue();
}
bool Queue::isEmpty() const
{
return topPtr == nullptr;
}
void Queue::enqueue(int data)
{
Node *newNodePtr = new Node(data);
if (topPtr == NULL)
{
topPtr = newNodePtr;
}
else
{
tailPtr->nextPtr = newNodePtr;
}
tailPtr = newNodePtr;
}
int Queue::dequeue()
{
if (isEmpty())
{
throw std::runtime_error("'dequeue' called on an already-empty queue");
}
// get top data
int dataToReturn = topPtr->data;
// advance top, retaining pointer to old node
Node *tmp = topPtr;
topPtr = topPtr->nextPtr;
// now delete the node
delete tmp;
// and reset tail if top hit end-of-queue
if (topPtr == nullptr)
tailPtr = nullptr;
// finally, return data
return dataToReturn;
}
int main()
{
std::cout << "Enter integers: ";
std::string line;
if (getline(std::cin, line) && !line.empty())
{
Queue integers;
std::istringstream iss(line);
int value;
while (iss >> value)
integers.enqueue(value);
while (!integers.isEmpty())
std::cout << integers.dequeue() << '\n';
}
}
Input
1 2 3 4 5
Output
Enter integers: 1 2 3 4 5
1
2
3
4
5
I have tried looking at videos and older posts but it is still very difficult to understand the concept of copy constructors. Would someone clear it up for me? My class did not really cover this part 100% my professor focused mainly on constructors and destructors.
Main CPP
#include <iostream>
#include "Header.h"
using namespace std;
int main()
{
node access;
access.getData();
access.outData();
system("pause");
return 0;
}
Header File
#include <iostream>
using namespace std;
class node
{
public:
node(); // Had to create my own default constructor because of my copy constructor.
node(const node &n); // This is a copy constructor.
~node();
void getData();
void outData();
private:
int num;
int lCount = 0; // Counts the number of nodes, increments after each user input.
int *ptr; // Where the linked list will be copied into
node *next;
node *first;
node *temp;
node *point;
};
node::node()
{
num = 0;
}
node::node(const node &n)
{
temp = first;
ptr = new node;
for (int i = 0; i < lCount; i++)
{
ptr[i] = temp->num;
temp = temp->next;
}
}
node::~node() // Deletes the linked list.
{
while (first != NULL)
{
node *delP = first; // Creates a pointer delP pointing to the first node.
first = first->next; // "Removes first node from the list and declares new first.
delete delP; // Deletes the node that was just removed.
}
cout << "List deleted" << endl;
}
void node::getData() // Simple function that creates a linked list with user input.
{
int input = 0;
point = new node;
first = point;
temp = point;
while (input != -1)
{
cout << "Enter any integer, -1 to end." << endl;
cin >> input;
if (input == -1)
{
point->next = NULL;
break;
}
else
{
lCount++;
point->num = input;
temp = new node;
point->next = temp;
point = temp;
}
}
}
void node::outData()
{
temp = first;
cout << "Original" << endl;
while (temp->next != NULL)
{
cout << temp->num << endl;
temp = temp->next;
}
cout << "Copied" << endl;
for (int i = 0; i < lCount; i++)
{
cout << ptr[i] << endl;
}
}
This little snippet is what I am having trouble with in particular:
node::node(const node &n)
{
temp = first;
ptr = new node;
for (int i = 0; i < lCount; i++)
{
ptr[i] = temp->num;
temp = temp->next;
}
}
I figured it out! I was tinkering with a much simpler copy constructor. I was having trouble understanding syntax, everything was very complicated and it was overwhelming to look at.
#include <iostream>
using namespace std;
class node
{
public:
node(int x); // Normal Construtor
node(const node &cpy); // Copy Constructor
void change(); // Changes data value
void outData();
private:
int data;
};
int main()
{
node var1(123);
var1.outData();
node var2 = var1;
var2.outData();
var2.change();
var1.outData();
var2.outData();
system("pause");
return 0;
}
node::node(int x)
{
data = x;
}
node::node(const node &cpy)
{
data = cpy.data;
}
void node::outData()
{
cout << data << endl;
}
void node::change()
{
int userIn;
cin >> userIn;
data = userIn;
}
Output:
123
123
(input: 4444)
Output:
123
4444
I am new to C++. I am trying to do an exercise where I supposed to read postfix operations into a queue and then evaluate it using stack. In my file every line includes only one postfix operation and all operations thus lines ends with #. But I couldn't make the reading part. My function for that only does it job for 2 times but it needs to do 3 times.
Here is what I managed to write so far:
//queue cpp file
#include<iostream>
#include <cassert>
#include "Queue.h"
#include "stdlib.h"
using namespace std;
Queue::Queue(){
Size = 0;
head = NULL;
rear = NULL;
}
Queue::~Queue(){
Node* curPtr = head;
while( curPtr != 0 ) {
Node* nex = curPtr->next;
delete curPtr;
curPtr = nex;
}
head = 0;
}
bool Queue::empty() const {
if(Size==0){
return true;
}
return false;
}
int Queue::size() const {
return Size;
}
void Queue::enqueue(ElementType x){
Node *newNode = new Node;
newNode->data = x;
if(Size == 0){
rear=head = newNode;
Size++;
}
else{
rear->next=newNode;
rear=rear->next;
Size++;
}
}
void Queue::dequeue(){
Node * newNode;
if(Size==1){
newNode=head;
rear=NULL;
head=NULL;
delete newNode;
}
else{
newNode=head;
head=head->next;
delete newNode;
}
Size--;
}
ElementType Queue::front(){
return head->data;
}
//queue .h file
#ifndef QUEUE
#define QUEUE
using namespace std;
typedef string ElementType; // type of item to be stored
class Queue{
public:
int size() const; //return the number of elements in the queue
bool empty() const; //return true if queue is empty, else return false
void enqueue(ElementType x); //add x to the queue, increasing size()
void dequeue(); //remove the element most recently added to the queue, decreasing size()
ElementType front(); //return the element most recently added to the queue
Queue();
~Queue();
private:
class Node{
public:
ElementType data;
Node * next;
};
Node * head;
Node * rear;
int Size;
};
#endif
// stack cpp file
#include<iostream>
#include <cassert>
#include "Stack.h"
#include "stdlib.h"
using namespace std;
Stack::Stack(){
Size = 0;
head = NULL;
}
Stack::~Stack(){
cout << "destructor called2" <<endl;
Node* deleter;
deleter=head;
Node* temp;
while(deleter!=NULL){
temp=deleter;
deleter=deleter->next;
delete temp;
}
}
bool Stack::empty() const {
if(Size==0){
return true;
}
return false;
}
int Stack::size() const {
return Size;
}
void Stack::push(ItemType x){
Node *newNode = new Node;
newNode->data = x;
if(Size == 0){
head = newNode;
Size++;
}
else{
newNode->next = head;
head = newNode;
Size++;
}
}
void Stack::pop(){
Node *newNode;
if(Size==1){
newNode=head;
head=NULL;
delete newNode;
}
else{
newNode=head;
head=head->next;
delete newNode;
}
Size--;
}
ItemType Stack::top(){
return head->data;
}
// stack .h file
#ifndef STACK
#define STACK
#include<iostream>
using namespace std;
typedef int ItemType; // type of item to be stored
class Stack{
public:
Stack();
~Stack();
int size() const; //return the number of elements in the stack
bool empty() const; //return true if stack is empty, else return false
void push(ItemType x); //add x to the stack, increasing size()
void pop(); //remove the element most recently added to the stack, decreasing size()
ItemType top(); //return the element most recently added to the stack
private:
class Node{
public:
ItemType data;
Node * next;
};
Node * head;
int Size;
};
#endif
//test .cpp file where operations happen and main is
#include "Stack.h"
#include "Queue.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
void operatorAndWriter(Queue& k, Stack &l, ofstream &myfile);
void reader(Queue &loko, Stack &l);
int main(){
Stack l;
Queue at;
reader(at, l);
return 0;
}
void reader(Queue &loko, Stack &l){
cout << "Enter the file name : " << endl;
string filename;
cin >> filename;
ifstream meinfile (filename);
string line;
string sub;
ofstream myfile("example.txt");
while (! meinfile.eof()){
getline (meinfile, line);
istringstream iss(line);
while (iss >> sub){
loko.enqueue(sub);
}
operatorAndWriter(loko, l, myfile);
meinfile.close();
}
myfile.close();
}
void operatorAndWriter(Queue &k, Stack &l, ofstream &myfile){
if(myfile.is_open()){
while (k.size()!=0){
string op = k.front();
if (op == "+"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(a+b);
myfile << "+ ";
}
else if (op == "-"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(b-a);
myfile << "- ";
}
else if (op == "*"){
int a = l.top();
l.pop();
int b = l.top();
l.pop();
l.push(a*b);
myfile << "* ";
}
else if (op == "#"){
myfile << "# " ;
myfile << l.top() << endl;
l.pop();
}
else{
int y;
y=atoi(op.c_str());
l.push(y);
myfile <<l.top()<<" ";
}
k.dequeue();
}
}
}
// here is the input file
23 4 * 19 2 - + #
6 3 - #
36 #
// here is my example file which i tried create and write operations and their solutions in it. however there is just one solution which belongs to the first sentence of the a.txt file.
23 4 * 19 2 - + # 109
This is really a lot of code. First some stylistic advice:
Use nullptr instead of NULL.
2. you should check if the File actually exists so you don't corrupt your memory by accident.
3. Simplify your code, and only post the important part.
4. Include guards should end with _H
Now to your problem:
I didn't read all of your code but first of all you can simplify your reading function by writing something like this:
ifstream meinfile ("input.txt",ios::in);
while (getline (meinfile,line)){
// Use line here
}
I don't know if this will help, but is a lot of code after all.
I am checking data of head node in constructor and its ok, but when i am checking it in the function then its gone. Why is it such a ghost this pointer ?
header for queue
#ifndef QUEUE_H
#define QUEUE_H
#include "Node.h"
#include "LinkedList.h"
class Queue
{
public:
Queue();
~Queue();
void addTail(Node* newNode);
Node* deleteHead();
int isEmpty();
void PrintQueue(char* outName);
protected:
private:
Node* head;
Node* tail;
LinkedList* myList;
};
#endif // QUEUE_H
queue class
#include "Queue.h"
Queue::Queue()
{
//constructor
myList = new LinkedList();
head = myList->getHead();
std::cout<<" head here is " << head->getData()<<std::endl; //
std::cout<<" next after head is " << head->getNext()->getData()<<std::endl; //
tail = myList->getTail();
}
void Queue::addTail(Node* newNode)
{
std::cout<<"inserting before tail (queue)"<<std::endl;
std::cout<<"new node is " << newNode->getData() <<std::endl;
std::cout<<" head here is " << myList->getHead()->getData() <<std::endl;
myList->insertLast(newNode);
}
Node* Queue::deleteHead()
{
if(isEmpty()){
std::cout<<"Queue is empty. Cannot remove anything anymore. Add more data to the queue!"<<std::endl;
return head;
}
return myList->removeFirst();
}
int Queue::isEmpty()
{
return myList->isEmpty();
}
void Queue::PrintQueue(char* outName)
{
Node* cur = head->getNext(); //store current node to keep track. Set it to one after the head
std::ofstream outfile;
outfile.open(outName, std::ios::app);
outfile << "Printing the values of the queue: ";
std::cout<<"Printing the values of the queue: "<<std::endl;
while(cur != tail)
{
std::cout<< cur->getData()<<", "<<std::endl; //print to the console
outfile << cur->getData() <<", "; //print to file
}
outfile.close();
}
Queue::~Queue()
{
//destructor
delete myList;
}
Main function
#include <iostream>
#include <fstream>
#include <string>
#include "Stack.h"
//#include "Stack.cpp"
#include "LinkedList.h"
//#include "LinkedList.cpp"
#include "Node.h"
//#include "Node.cpp"
#include "HashTable.h"
//#include "HashTable.cpp"
using namespace std;
int main( int argc, char* argv[] )
{
//specifying the in and out files
char* inFileName = argv[1];
char* outFileName = argv[2];
std::fstream infile (inFileName) ; // input file
//open the input file and find largest integer
int num;
int largest = 0;
Stack * myStack = new Stack();
char buffer[33]; //create a buffer for using with itoa
std::ofstream outfile;
outfile.open(outFileName);
if ( !infile.is_open() ) //check if input file is open
cout<<"Could not open file\n";
else {
while (infile >> num) { // read file int by int and check if current is not the largest
if(num > largest) largest = num;
Node *newNode= new Node(itoa(num,buffer,10));
myStack->push(newNode);
}
}
std::cout<< std::endl;
infile.close(); //close files that you read to avoid memory leaks
myStack->PrintStack(outFileName);
HashTable* hashBrown = new HashTable();
int currentDigit = 0;
int currentTable = 0;
int numOfDig =0; //stores number of digits of the largest number
string maxNum = itoa(largest,buffer,10);
numOfDig = maxNum.length();
std::cout<< "Num of digits " << numOfDig << std::endl;
Node* current;
while(!myStack->isEmpty())
{
current = myStack->pop();
std::cout<< "pop from stack element " << current->getData() << std::endl;
string str = current->getData();
int index = atoi(&str.back());
std::cout<< "insert at index " << index << std::endl;
std::cout<< "inserting data: "<< current->getData()<< " at index:" << index << std::endl;
hashBrown->myQueues[index].addTail(current);
}
hashBrown->printHashTable(outFileName);
delete myStack;
delete hashBrown;
outfile.close();
std::cout<< "finishing program " << std::endl;
return 0;
}
Linked List
#include "LinkedList.h"
#include "Node.h"
LinkedList::LinkedList()
{
//constructor
head = new Node("head"); //dummy variable
tail = new Node("tail"); //dummy variable
head->setNext(tail);
}
void LinkedList::insertNode(Node* newNode, Node *position)
{
newNode->setNext(position->getNext()); // set its pointer to position
position->setNext(newNode);
}
void LinkedList::insertFirst(Node* newNode)
{
std::cout<<"head here is "<< head->getData() <<std::endl; //
insertNode(newNode, head);
}
void LinkedList::insertLast(Node* newNode)
{
std::cout<<"inserting before tail (LinkedList)"<<std::endl; //
Node* cur = head;
std::cout<<"outside the loop "<< cur->getData() <<std::endl; //
std::cout<<"current node is "<< cur->getData() <<std::endl; //
while(cur->getNext() != tail) //iterate until you reach one before tail
{
std::cout<<"current node is "<< cur->getData() <<std::endl; //
cur = cur->getNext();
}
std::cout<<"inserting before tail"<<std::endl; //
insertNode(newNode, cur); //insert at the end before the dummy tail
}
Node* LinkedList::removeFirst()
{
if(isEmpty())
{
return head;
}
Node* result = head->getNext(); //store pointer to Node that you need to return
head->setNext(result->getNext());
return result;
}
Node* LinkedList::getTail()
{
return tail;
}
Node* LinkedList::getHead()
{
return head;
}
int LinkedList::isEmpty()
{
return head->getNext() == tail;
}
std::string LinkedList::printList(){
Node *current = head;
std::string str;
//append pieces of string to create new line
while(current != tail){
str.append (" --> (");
str.append ( current->getData());
str.append (",");
str.append (current->getNext()->getData());
str.append (")") ;
current = current->getNext();
}
std::cout<<str<<std::endl; //display new
return str; //return string containing next line that will be written to a file in main
}
LinkedList::~LinkedList()
{
//destructor
Node *current = head;
while( current->getNext() != tail ) { //go through whole linked list and delete each node to free memory
Node* next = current->getNext();
delete current;
current = next;
}
delete current;
delete tail;
}
So everything works fine until it tries to access the head or its data in the addTail() function of Queue.
You can use gdb to debug your program, find the bugs and fix them. If the program cored, you can use backtrace to see what caused the core.
Set breakpoint at the lines you think program behavior wired, you can also let the program run step by step.
Run the program and print variable value to see whether the variable value is expected. If the variable is a pointer, you can also print the content it referenced.
A brief gdb tutorial
my code is suppose to create a singly linked list using and array of nodes.
each Node has variable item which hold data and variable next which holds the index of the next node in the list. the last node has -1 in its next data field to simulate a nullptr. head holds the index of the first node in the list.
for some reason when i try to create new memory the program throws an instance of bad_alloc
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
#include "ArrayList.h"
#include <iostream>
using namespace std;
ArrayList::ArrayList(char ch){
array = new Node[Size];
(array[0]).item = ch;
(array[0]).next = 1;
free = 1;
head = 0;
}
bool ArrayList::cons(char ch) {
if (this->isFull()){
this->doubleArray();
}
(array[free]).item = ch;
(array[free]).next = head;
head = free;
free++;
// cout << free << endl;
return true;
}
bool ArrayList::isFull() const{
int current = head;
int count =0;
while( (array[current]).next != -1 ){
count++;
current = (array[current]).next;
}
return (count == Size) ? true : false;
}
bool ArrayList::doubleArray() {
int oldSize = Size;
Size *=2;
Node* newArray = new Node[Size]; // problem occurs here, i think
int count =0;
while(oldSize >= count ){
(newArray[count]).item = (array[count]).item;
(newArray[count]).next = (array[count]).next;
count++;
}
free = count +1;
delete [] array;
array = newArray;
cout <<"free: "<< free << endl;
return true; // come up with thiss
}
void ArrayList::print() const{
if (head == -1) return;
int current = head;
cout << "[ ";
while( (array[current]).next != -1){
cout << (array[current]).item <<" ";
current = (array[current]).next;
}
cout << (array[current]).item <<"]";
return;
}
///////////////////////////////////
#ifndef ARRAYLIST_H
#define ARRAYLIST_H
#include <iostream>
using namespace std;
class Node{
public:
char item;
int next;
Node(){
next = -1;
}
Node(char input){
this->item = input;
next = -1;
}
};
class ArrayList{
public:
ArrayList(char ch);
int length() const;
void print() const;
private:
bool doubleArray();
bool isFull() const;
Node* array;
int Size = 5;
int head = -1;
int free = 0;
};
#endif
////////////////////////////////////////
#include <iostream>
#include "ArrayList.h"
using namespace std;
int main(){
ArrayList list('1');
list.cons('2');
list.cons('3');
list.cons('4');
list.cons('5');
list.cons('6');
list.cons('7');
list.print();
//cout << list.length();
return 0;
}