C++ Pop Function Linked List - c++

I am writing a program that implements stacks as linked lists. The program complies but when I run it, it crashes. I ran the debugger and says unhandled exception when it gets inside the Pop() function and to the line "topPtr = topPtr->next". I was wondering if anyone noticed something in there that is causing this error. I attached the portion of main and the pop function that I believe i sbeing affected. thanks
template<class ItemType>
struct NodeType
{
ItemType info;
NodeType* next;
};
template<class ItemType>
class Stack
{
private:
int stacklength;
NodeType<ItemType>* topPtr; // It points to a singly-linked list
public:
void Pop(ItemType &x);
template<class ItemType>
void Stack<ItemType>::Pop(ItemType &x)
{
NodeType<ItemType>* tempPtr;
tempPtr = topPtr;
topPtr = topPtr->next;
delete tempPtr;
stacklength--;
}
int main()
{
Stack <int> IntStack;
int x;
IntStack.Pop(x);
}

First off, you don't initialize your pointers.
template<class ItemType>
struct NodeType
{
//...
NodeType() : next(nullptr) {} ///Initialize next so we can check for null
};
template<class ItemType>
class Stack
{
public:
Stack() : topPtr(nullptr), stacklength(0) { } ///initialize
//...
Then, in your Pop, you need to check for an empty stack (you can't pop if there are no elements).
template<class ItemType>
void Stack<ItemType>::Pop(ItemType &x)
{
if (!topPtr)
{
//Here, we need to decide how to handle this.
//One way would be to throw an exception,
//another way would be to change the method signature
//and return a bool.
}
///...
}

Related

Why am I getting bad_alloc? Implementing a stack c++

I'm trying to implement my own Stack in C++ but I keep getting this error when I try to use the method pop() in which what I'm trying to do is:
Save element from the top in a variable called "res".
Get the reference to the next element from the node class and set it as the top.
size--
Return the variable "res".
If you could help me I'd appreciate it. Thank you!
Node class:
template<class T>
class Node {
private:
Node<T>* next;
T element;
public:
Node();
Node(const Node& orig);
~Node();
void setElement(T el);
T getElement();
Node<T>* getNext();
void setNext(Node<T>* ne);
};
Stack class:
#include "EmptyStackException.cpp"
#include "Node.cpp"
#include <iostream>
using namespace std;
template<class T>
class LinkedStack {
private:
int siz;
Node<T>* first;
public:
LinkedStack();
~LinkedStack();
int size();
bool isEmpty();
void push(T e);
T top();
T pop();
};
template<class T>
void LinkedStack<T>::push(T e) {
Node<T> node = Node<T>();
node.setNext(first);
node.setElement(e);
first = &node;
siz++;
}
template<class T>
T LinkedStack<T>::pop() {
T res = first->getElement();
first = *(first->getNext());
siz--;
}
template<class T>
void LinkedStack<T>::push(T e) {
Node<T> node = Node<T>();
node.setNext(first);
node.setElement(e);
first = &node;
siz++;
}
Since node is an object that is local to this function, as soon as this function ends, it is destroyed. However, first contains a pointer to it. So when this function returns, first contains a pointer to an object that no longer exists. You probably want this:
template<class T>
void LinkedStack<T>::push(T e) {
Node<T>* node = new Node<T>();
node->setNext(first);
node->setElement(e);
first = node;
siz++;
}
Now, node still ceases to exist when this function returns. But first doesn't contain a pointer to node, it contains the value of node -- a pointer to a dynamically allocated object.
Note that you will have to manage the lifetime of that object somehow. Ideally, you wouldn't use raw pointers so that you don't have that burden.

Removing the first element in a linked list C++

I'm trying to write a function which removes an element in a linked list. I'm only having trouble with removing the head of the list. I'm able to remove any other element just fine. Here's my code (I only included the part of the function which deals with deleting the head).
template <class T>
void SinglyLinkedList<T>::remove(std::size_t i) {
//i is the element to be deleted
SinglyLinkedListNode *p=head;
// checks if the size is 0 or if the node isn't in the list
if( size()==0 && i>=size())
return;
//check if first element
if(i==0){
head=head->next;
//delete p;
}
}
My problem is with freeing the memory (I commented out the deleting here). When I comment it out like I am now it works fine (but obviously results in a memory leak) but when I uncomment it I get a segmentation fault and I'm not sure why. Any help would be appreciated.
Update: I'm sorry, I forgot to include the rest of my code: Here's the implementation:
template <class T>
class SinglyLinkedList {
// Nested class representing the nodes in the list.
class SinglyLinkedListNode {
public:
// The value stored in this node.
T value;
// The next node in the sequence.
SinglyLinkedListNode *next;
SinglyLinkedListNode(T value) :
value(value), next(nullptr) {}
SinglyLinkedListNode(T v, SinglyLinkedListNode *n) :
value(v), next(n) {}
// Return the size (length) of the linked list.
std::size_t size();
};
SinglyLinkedListNode *head;
SinglyLinkedListNode *tail;
public:
// Constructs a new SinglyLinkedList from an initializer_list of type T[].
// This is mostly for convenience, especially when testing.
SinglyLinkedList(std::initializer_list<T> items): head(nullptr), tail(nullptr)
{
if (items.size() == 0) {
return;
}
// initializer_lists were designed to be used iteratively,
// so thats what we do.
auto it = items.begin();
while (it != items.end()) {
this->push_back(*it++);
}
}
T* at(std::size_t i);
void push_back(T value);
void push_front(T value);
std::size_t size();
void remove(std::size_t i);
void insert(std::size_t i, T value);
void append(SinglyLinkedList<T> list);
So I'm creating a linked list using an initializer list and then trying to remove that element. But it's failing
SinglyLinkedList<int> lst = {100, 200, 300, 400, 500};
lst.remove(0);
Update 2: By request here's my push_back function
template <class T>
void SinglyLinkedList<T>::push_back(T value) {
//when empty
if(head==nullptr){
head= new SinglyLinkedListNode(value);
tail=head;
}
//when not empty
else{
tail->next= new SinglyLinkedListNode(value);
tail= tail->next;
}
}

Stack Inheritance

I have just finished a project for Post Fix Notation(RPN) using stack. I am not having much luck with some of the compiler errors so I come to you guys while I work on debugging on my side also.
This file given to us. We are suppose to derive a stack class from it.
#ifndef ABSTRACTSTACK_H
#define ABSTRACTSTACK_H
#include <string>
using namespace std;
/* --------------- Class 'Oops' ---------------
Class
Thrown when an error is encountered.
Member 'm_msg' stores an error message.
*/
class Oops
{
string m_errormsg;
public:
Oops(string msg) : m_errormsg(msg) {}
const string& getMsg() const
{
return m_errormsg;
}
};
/* --------------- Abstract Class AbstractStack --------------- */
template < typename T >
class AbstractStack
{
public:
// Purpose: Checks if a stack is empty
// Returns: 'true' if the stack is empty
// 'false' otherwise
virtual bool isEmpty() const = 0;
// Purpose: looks at the top of the stack
// Returns: a const reference to the element currently on top of the stack
// Exception: if the stack is empty, THROW a 'Oops' object with an error message!!!
virtual const T& top() const throw ( Oops ) = 0;
// Purpose: push an element into the stack
// Parameters: x is the value to push into the stack
// Postconditions: x is now the element at the top of the stack,
virtual void push(const T& x) = 0;
// Purpose: pop the stack
// Postconditions: the element formerly at the top of the stack has
// been removed
// Note: Poping an empty stack results in an empty stack.
virtual void pop() = 0;
// Purpose: clears the stack
// Postconditions: the stack is now empty
virtual void clear() = 0;
};
#endif
Here is my derived class and it's implementation.
#ifndef STACK_H
#define STACK_H
#include<string>
#include<iostream>
#include<cstdlib>
#include "abstractstack.h"
using namespace std;
template<typename T>
struct Node
{
T Data;
Node<T>* next;
};
template<typename T>
class Stack : public AbstactStack<T>
{
private:
Node<T>* Top;
public:
//Purpose: Destructor
//Postconditions: The stack is now empty
~Stack() {};
//Purpose: Default Constructor
//Postconditions: Top is initialized to 'NULL'
Stack(); Top(NULL){};
//Overloaded = Operator
//Postconditions: *this is now equal to rhs
const Stack<T>& operator = (const Stack<T>& rhs);
//Purpose: Check if a stack is empty
//Returns: 'true' if the stakc is empty, 'false' otherwise
bool isEmpty() const;
//Purpose: Looks at the top of the stack
//Returns: a const reference to the element currently on top of the stack
//Exception: if the stack is empty, THROW a 'Oops' object with an error message!!!"
const T& top() const throw(Oops);
//Purpose: push an element into the stack
//Parameters: x is the value to push into the stack
//Postconditions: x is now the element at the top of the stack
void push(const T& x);
//Purpose: pop the stack
//Postconditions: the element formerly at the top of the stack has been removed
//Popping an empty stack results in an empty stack
void pop();
//Purpose: clears the stack
//Postconditions: the stack is now empty
void clear();
//Reverses the stack
//Postconditions: stack is now in reverse order
void reverse();
};
#include "stack.hpp"
#endif
Implementation (.hpp)
#include <string>
#include <iostream>
using namespace std;
template<typename T>
const Stack<T>& Stack<T>::operator = (const Stack<T>& rhs)
{
if (this != &rhs)
{
if (Top != NULL)
clear();
Node<T>* rhsPtr = rhs.Top;
Node<T>* copyPtr = Top = new Node<T>;
copyPtr->Data = rhsPtr->Data;
while (rhsPtr->next != NULL)
{
rhsPtr = rhsPtr->next;
copyPtr->next = new Node<T>;
copyPtr = copyPtr->next;
copyPtr->Data = rhsPtr->Data;
}
copyPtr->next = NULL;
}
return(*this)
}
template<typename T>
Stack<T>::Stack(const Stack<T>& rhs)
{
Top = NULL;
*this = rhs;
}
template<typename T>
bool Stack<T>::isEmpty()
{
return(Top == NULL);
}
template<typename T>
const T& top() const throw(Oops)
{
if (Top != NULL)
return(Top->Data);
else
throw Oops(Stack is Empty!);
}
template<typename T>
void Stack<T>::push(const T& x)
{
Node<T>* newNode = new Node;
newNode->Data = x;
if (isEmpty())
{
Top = newNode;
return;
}
newNode->next = Top;
Top->next = newNode;
}
template<typename T>
void Stack<T>::pop()
{
Node<T>* temp;
if (Top != NULL)
{
temp = Top;
Top = Top->next;
delete temp;
}
}
template<typename T>
void Stack<T>::clear()
{
Node<T>* temp;
while (Top != NULL)
{
temp = Top;
Top = Top->next;
delete temp;
}
}
template<typename T>
void Stack<T>::reverse()
{
Node<T>* current;
Node<T>* previous;
Node<T>* next;
previous = NULL;
current = Top;
while (current != NULL)
{
next = current->next;
current->next = previous;
previous = current;
current = next;
}
Top = previous;
}
The compiler is unhappy with my Stack class. "stack.h:25:34: error: expected template-name before ‘<’ token
class Stack : public AbstactStack
I've been told that I cannot inherit from Abstract because it is not a class but my professor tells me that it is fine and that I should add a forward declaration in my .cpp of Stack but I'm not sure how this goes. I know I am far from done but I would like to be able to solve at least this error so I can see if my program works correctly or not.
I posted my main program into Pastebin with its headers and implementation here in case it is needed. http://pastebin.com/1t2YGa2c
Seems to me that the problem that you are having is just a typo in the following line :
class Stack : public AbstactStack<T>
Change AbstactStack<T> to AbstractStack<T> and this should work.
The error you are getting explains that the class name before the character < should be a template, but since you made a typo in the name of the class, it does not recognize.
Make sure you read and understand the error messages! They are often very helpful when solving problems like these.
Little side note : If you take a look at your error messages, you'll see the filename where the error is, followed by the line number and the column number (stack.h:25:34). Very useful information when debugging.

Dynamic Queue C++

template<class T>
class QueueD: public IQueue<T>{
private:
Node<T> *QFront, *QRear;
public:
QueueD(): QFront(NULL), QRear(NULL){}
bool empty()const{
return QFront==NULL;
}
bool enqueue(const T &info){
Node<T> *p=new Node<T>(info,NULL);
if(QFront==NULL)
QFront=p;
else
QRear->setNext(p);
QRear=p;
return true;
}
bool dequeue(T &info){
if (empty()) return false;
else{
info=QFront->getInfo();
Node<T> *p=QFront;
if(QRear==QFront)
QRear=NULL;
QFront=QFront->getNext();
delete p;
return true;
}
}
};
template<class T>
class Node{
private:
T info;
Node *next;
public:
Node(const T &c, Node *p): info(c), next(p){
}
Node *getNext()const{
return next;
}
void setNext(Node *p){
next=p;
}
T &getInfo(){
return info;
}
};
I've been trying to understand C++ a little better, I was wondering if you guys could explain me a few lines of code that I do not understand here.
QFront=QFront->getNext();
How does QFront know which node is next? In the code it is only set for QRear.
if(QRear==QFront) {QRear=NULL;}
And why is this necessary?
edit: added Node template
When queue is empty QFront == QRear, so when you set next element for QRear, you'll effectively set up next element for QFront, too. That's how QFront knows which element is next.
I believe that setting QRear to NULL in dequeue is unnecessary since it's not used in enqueue in case of empty queue.

C++ pass by reference then set a pointer to the object

I am creating a class LinkedList. I am having difficulty adding another node to my list.
Here is what I have so far:
template<typename T>
class LinkedList
{
private:
T element;
T *next;
public:
LinkedList();
LinkedList(T element);
void add(LinkedList<T> &otherList);
void print();
};
template<typename T>
LinkedList<T>::LinkedList()
{
next = NULL;
}
template<typename T>
LinkedList<T>::LinkedList(T element)
{
this->element = element;
next = NULL;
}
template<typename T>
void LinkedList<T>::add(LinkedList<T> &otherList)
{
next = &otherList;
}
template<typename T>
void LinkedList<T>::print()
{
LinkedList<T> *current = this;
while (current != NULL)
{
std::cout << current->element;
current = current->next;
}
}
int main()
{
LinkedList<std::string> myFirst("First");
LinkedList<std::string> mySecond("Second");
myFirst.add(mySecond);
myFirst.print();
return 0;
}
This works however if I make the change:
void add(const LinkedList<T> &otherList);
template<typename T>
void LinkedList<T>::add(const LinkedList<T> &otherList)
{
next = &otherList; //now an error right here
}
Then I get an error stating:
Assigning to 'LinkedList<std::__1::basic_string<char> > *' from incompatible type 'const LinkedList<std::__1::basic_string<char> > *'
Why is it I get this error?
next is a T*, and you're trying to assign a const LinkedList<T>* to it.
I suppose you meant something like next = &(otherList.element) (though even then I think your list semantics are somewhat broken — elements shouldn't typically be shared by multiple containers unless you're very, very clear about the ownership semantics).
Contrary to your claims, your first program doesn't work either for the same reason.