I need to design a program using linked list stack to receive an input then gene
ID: 3771191 • Letter: I
Question
I need to design a program using linked list stack to receive an input then generate its output according to the operand and operator inserted. For example if I typed "1 2 3 X C" it will push only the operand to the stack so 1 2 3 will be pushed then reading X to print out the stack, and C to clear the stack. The other operators are S and P to sum and multiply all the values in the stack, pop all values then put the result back to the stack. + - * / will pop two operand then push only result back to the stack, ! to negative an operand (pop then push the result back to the stack), and $ to end the program.
My question is I'm using 'valgrind' to detect memory leaks and I always comeup with at least 24 bytes lost. I couldn't remember the exact amount but as I inputted more lines it sometimes increased to 48 bytes or 96. I tried to input just 1 > enter > $, the program already have the memory leaks of 24 bytes. I can't find why I have the leaks. Could anyone help me or explain why there's a memory leaks?
Below are the codes I'm coding, I was given the abstractstack.h then I need to implement LLStack.h and program.cpp by myself.
program.cpp
#include <string>
#include <cstdlib>
#include <iostream>
#include "abstractstack.h"
#include "llstack.h"
using namespace std;
int main ()
{
const char OPER[10]={'+','-','*','/','!','S','P','X','C','$'};
LLStack <int> A;
A.clear();
char in1;
int x,y;
int loop1=0;
int positionOper=0;
int result=0;
bool check=false;
do
{
cin>>in1;
check=false;
loop1=0;
while(loop1<10)
{
if(in1==OPER[loop1])
{
check=true;
positionOper=loop1;
loop1=10; //make it stop looping
}
loop1++;
}
if(check==false)
{
x=in1-'0';
//x=atoi(in1.c_str());
A.push(x);
}
else
{
if((A.isEmpty()==false)&&(positionOper<4)) //+ - * /
{
x=A.top();
A.pop();
y=A.top();
A.pop();
}
switch(positionOper)
{
case 0:
result=x+y;
break;
case 1:
result=y-x;
break;
case 2:
result=x*y;
break;
case 3:
result=y/x;
break;
case 4:
x=A.top();
result=(-1)*x;
break;
case 5:
result=A.sumLLStack();
A.clear();
break;
case 6:
result=A.productLLStack();
A.clear();
break;
case 7:
A.printList();
break;
case 8:
A.pop();
A.pop();
A.clear();
break;
}
if(positionOper<4) // + - * /
{
A.push(result);
}
else if(positionOper==4)
{
A.pop();
A.push(result);
}
}
}while(in1!='$');
A.clear();
return 0;
}
Abstractstack.h
/* @file: abstractstack.h
* Definition of templated class stack
* Implementing A.D.T. Stack
* @C - Galaxy Express Software
*
* Version 15.3.0
*/
/* ____________________
/
| AbstractStack Class |
____________________/
Purpose: Implements a Stack ADT using.
Error Handling: Whenever a function is given invalid parameter values
THROWS a 'Oops' object.
*/
#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(const 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;
// Purpose: DESTRUCTOR
virtual ~AbstractStack() {}
};
#endif
LLStack.h
#ifndef LLSTACK_H
#define LLSTACK_H
#include "abstractstack.h"
template <typename T>
class LLStack: public virtual AbstractStack<T>
{
protected:
T m_data;
LLStack* m_next;
public:
LLStack(): m_next(NULL){}
int getData(const int position)
{
int data=0;
if(!isEmpty())
{
if(position==0)
data=m_data;
else if(position==1)
data=m_next->m_data;
}
return data;
}
// Purpose: Checks if a stack is empty
// Returns: 'true' if the stack is empty
// 'false' otherwise
bool isEmpty() const
{
if(m_next==NULL)
return true;
else
return false;
}
// 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 )
{
if(m_next!=NULL)
return this->m_data;
else
throw Oops("The stack is empty");
}
// 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)
{
LLStack* tmp=new LLStack;
tmp->m_data=m_data;
tmp->m_next=m_next;
m_data=x;
m_next=tmp;
tmp=NULL;
delete tmp;
}
// 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.
void pop()
{
if(m_next!=NULL)
{
LLStack* tmp=m_next;
m_data=tmp->m_data;
m_next=tmp->m_next;
delete tmp;
}
}
// Purpose: clears the stack
// Postconditions: the stack is now empty
void clear()
{
m_next=NULL;
while(isEmpty()==false)
{
pop();
}
}
void printList()
{
cout<<"[ ";
if(isEmpty()==false)
{
LLStack* tmp=this;
while(!(tmp->isEmpty()))
{
cout<<tmp->m_data<<" ";
tmp=tmp->m_next;
}
// delete tmp;
}
cout<<"]"<<endl;
}
int sumLLStack()
{
LLStack* tmp=this;
int result=0;
while(tmp->m_next!=NULL)
{
result+=tmp->m_data;
tmp=tmp->m_next;
}
delete tmp;
return result;
}
int productLLStack()
{
LLStack* tmp=this;
int result=1;
while(tmp->m_next!=NULL)
{
result*=tmp->m_data;
tmp=tmp->m_next;
}
delete tmp;
return result;
}
~LLStack()
{
m_next=NULL;
}
};
#endif
#include <string>
#include <cstdlib>
#include <iostream>
#include "abstractstack.h"
#include "llstack.h"
using namespace std;
int main ()
{
const char OPER[10]={'+','-','*','/','!','S','P','X','C','$'};
LLStack <int> A;
A.clear();
char in1;
int x,y;
int loop1=0;
int positionOper=0;
int result=0;
bool check=false;
do
{
cin>>in1;
check=false;
loop1=0;
while(loop1<10)
{
if(in1==OPER[loop1])
{
check=true;
positionOper=loop1;
loop1=10; //make it stop looping
}
loop1++;
}
if(check==false)
{
x=in1-'0';
//x=atoi(in1.c_str());
A.push(x);
}
else
{
if((A.isEmpty()==false)&&(positionOper<4)) //+ - * /
{
x=A.top();
A.pop();
y=A.top();
A.pop();
}
switch(positionOper)
{
case 0:
result=x+y;
break;
case 1:
result=y-x;
break;
case 2:
result=x*y;
break;
case 3:
result=y/x;
break;
case 4:
x=A.top();
result=(-1)*x;
break;
case 5:
result=A.sumLLStack();
A.clear();
break;
case 6:
result=A.productLLStack();
A.clear();
break;
case 7:
A.printList();
break;
case 8:
A.pop();
A.pop();
A.clear();
break;
}
if(positionOper<4) // + - * /
{
A.push(result);
}
else if(positionOper==4)
{
A.pop();
A.push(result);
}
}
}while(in1!='$');
A.clear();
return 0;
}
Explanation / Answer
Memory leaks happens in a program whenever a allocated memory is there and it is not freed.
The problem is there in the print list function where the allocated temp is not deleted. void printList()
{
cout<<"[ ";
if(isEmpty()==false)
{
LLStack* tmp=this;
while(!(tmp->isEmpty()))
{
cout<<tmp->m_data<<" ";
tmp=tmp->m_next;
}
// delete tmp;
}
cout<<"]"<<endl;
delete temp should not be commented here. This should fix the leak problem.
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.