Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 5 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
Well I am doing an assignment but not sure what my problem is
this is my assignment
Instructions You have two parts to this assignment. The parts are related, but different in their implementation. To better understand the assignment itself, it may be helpful to go back through the book, slides, notes, etc. and do implementations of the regular array-based and linked list-based Stack, along with the Stack ADT.
Part I
One widespread use of stacks is to provide the undo operation, familiar to us from many different applications. While support for undo can be implemented with an unbounded stack (one that keeps growing and growing as long as memory permits), many applications provide only limited support for such an undo history. In other words, the stack is fixed-capacity.
When such a stack is full, and push is invoked, rather than throwing an exception, a more typical approach is to accept the pushed element at the top, while removing the oldest element from the bottom of the stack to make room. This is known as “leaking.” Note that this does not mean that the ADT exposes a method to allow removal from the bottom directly. This is only performed when the stack becomes full.
For this part, you are to give an implementation of such a LeakyStack abstraction, using some array-based implementation.
Note that you must create a Leaky Stack interface, and then use the C++ : operator to implement that interface (using public inheritance) with your LeakyArrayStack implementation. See the Interface specified near the end of the assignment instructions.
Part II Repeat Part I, but use a singly linked list instead of an array for the actual data storage, and allow for a maximum capacity specified as a parameter to the constructor.
NOTES: • Both the array-based and linked-list based Leaky Stacks should use the same LeakyStackInterface, specified below. Remember – this is a LeakyStack ADT. It specifies what the LeakyStack does, not how. So, the interface should not be different in order to provide an implementation. • Use public inheritance in both Parts • You should write a SinglyLinkedList class first, before trying to do part II o Then, use containment (aggregation or composition, a has-a relationship) to implement the part II
I GOT TO USE THE INTERFACE IN THE PICTURE
this is my code
#include <iostream>
#ifndef LEAKYStacksINTERFACE
#define LEAKYStacksINTERFACE
#define cap 10
using namespace std;
template<typename ItemType>
class LeakyStacksInterface
{ public:
//returns whether Stacks is empty or not
virtual bool isEmpty() const = 0;
//adds a new entry to the top of the Stacks
//if the Stacks is full, the bottom item is removed
//or "leaked" first, and then the new item is set to the top
//---> If the Stacks was full when the push was attempted, return false
//---> If the Stacks was not full when the push was attempted, return true
virtual bool push(const ItemType& newEntry) = 0;
//remove the top item
//if the Stacks is empty, return false to indicate failure
virtual bool pop() = 0;
//return a copy of the top of the Stacks
virtual ItemType peek() const = 0;
//destroys the Stacks and frees up memory
//that was allocated
// virtual ~StacksInterface() {}
};
template<typename ItemType>
struct node
{
int data;
struct node *next;
};
template<typename ItemType>
class Stacks : public LeakyStacksInterface<ItemType>
{
struct node<ItemType> *top;
public:
int size;
ItemType *myArray;
Stacks()
{
top=NULL;
size = 0;
myArray = new ItemType[cap];
}
~Stacks() {
size = 0;
}
public:
// pure virtual function providing interface framework.
bool isEmpty() const {
return(size == 0);
}
bool push(const ItemType& newEntry) {
if(size == cap) {
for(int i = 0; i < size-1; i++) {
myArray[i] = myArray[i+1];
}
myArray[size-1] = newEntry;
return false;
}
}
ItemType peek() const {
return myArray[size-1];
}
void display()
{
cout<<"Stacks: [ ";
for(int i=size-1; i>=0; i--)
{
cout<<myArray[i]<<" ";
}
cout<<" ] "<<endl;
}
};
int main()
{
Stacks s;
int choice;
while(1)
{
cout<<"n-----------------------------------------------------------";
cout<<"nttSTACK USING LINKED LISTnn";
cout<<"1:PUSHn2:POPn3:DISPLAY STACKn4:EXIT";
cout<<"nEnter your choice(1-4): ";
cin>>choice;
switch(choice)
{
case 1:
s.push();
break;
case 2:
s.pop();
break;
case 3:
s.show();
break;
case 4:
return 0;
break;
default:
cout<<"Please enter correct choice(1-4)!!";
break;
}
}
return 0;
}
#endif
HERE ARE MY ERRORS :
ERROR:missing template arguments before 's'
ERROR:expected ';' before 's'
ERROR:'s' was not delcared in this scope
please help!
Thank You!
INTERFACE PICTURE
Stacks is a class template, so to use it you must provide a template argument, like
Stacks<int> s;
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm trying to sort a stack by using another stack and a temporary variable. In the sort function, when I'm trying yo return the address of the second stack I'm not sure what type it is returning. Because I'm getting two errors:
file0.cpp: In function 'int main()':
file0.cpp:97:23: error: cannot convert 'int*' to 'stack*'
97 | arr.ad = sort(one.a);
and
file0.cpp:46:17: note: initializing argument 1 of 'int sort(stack*)'
46 | int sort(stack* obj){
| ~~~~~~~^~~
So, these are the errors I'm getting. I'm tried many things by changing the sort function to:
stack* sort();
int* sort();
None of them are working well. So could anyone please explain what is wrong with the code and correct it? And what are topics I must learn better to not make such mistakes again?
#include <iostream>
#define MAX 101
using namespace std;
class stack{
public:
int top = -1, a[MAX];
int address;
void push(int x){
a[++top] = x;
}
void pop(){
top = top - 1;
}
bool isEmpty(){
if(top == -1){
return true;
}else{
return false;
}
}
int Top(){
return top;
}
void print(stack* arr){ //a function to print the stack just confirmaion
for(int i = 0; i < top; i++){ //that the stack is sorted
cout << arr->a[i];
}
}
};
int sort(stack* obj){ //function to sort the stack
int n = obj->top;
int temp = obj->a[n]; //a variable to hold the element
//if it is greater than the Top stack during sorting
stack two; //second stack for sorting the elements
if(two.isEmpty()){ //
two.push(temp);
}
while(obj->top != 0){
if((temp > obj->a[obj->top]) & (two.a[two.top] > temp)){
two.push(temp);
}else if(two.a[two.top] > obj->a[obj->top]){
two.push(obj->a[obj->top]);
obj->pop();
}else{
temp = obj->a[obj->top];
obj->pop();
obj->push(two.a[two.top]);
two.pop();
}
}
return two.a; //trying to return
//address of the second stack that I created
}
int main() {
stack one;
one.push(12); //pushing into the stack
one.push(1);
one.push(19);
one.push(14);
one.push(7);
one.push(79);
one.push(3);
stack* a;
a->address = sort(one.a);
one.print(a->address);
return 0;
}
```
Well many things wrong here. A pointer to a stack is stack*, but two.a is not a pointer to a stack it's a pointer to the a array inside that stack, that would be int*.
But the whole approach is wrong. stack two is a local variable inside your sort function. Because of this it is destroyed when you exit the sort function. So if you were to return a pointer to it, or a pointer to the array inside of it, you will be returning a pointer to something that no longer exists and your program will crash.
The simple way to handle this is to return the stack itself, not a pointer. I've also changed sort and print so that they use references instead of a pointers.
It seems (like many beginners) you are far too quick to use pointers to solve problems that are better solved in other ways. Pointers are definitely an advanced feature of C++, but are rarely needed in good quality C++ code.
Like this
stack sort(stack& obj)
{
int n = obj.top;
...
stack two;
...
return two;
}
void print(const stack& arr){
...
}
int main()
{
stack one;
one.push(12);
...
stack a = sort(one);
print(a);
}
I am working on a medium sized C++ framework making use of the visitor pattern.
A valgrind test of a program implementing this framework reported a number of memory leaks that could be tracked down to one of the visitors, namely the copyCreator.
template<typename copyNodeType>
struct copyCreator {
copyCreator {}
copyCreator(node * firstVisit) {
firstVisit->accept(*this);
}
~copyCreator() {
copy.reset();
for(auto ptr : openList) {
delete ptr;
}
}
std::unique_ptr<copyNodeType> copy = 0;
vector<nonterminalNode *> openList;
// push to tree
template<typename nodeType>
void push(nodeType * ptr) {
if (copy) {
// if root is set, append to tree
openList.back()->add_child(ptr);
}
else {
auto temp = dynamic_cast<copyNodeType *>(ptr);
if(temp) {
copy = std::unique_ptr<copyNodeType>(temp);
}
}
}
// ...
void visit(struct someNonterminalNode & nod) {
auto next = new someNonterminalNode(); //This is leaked
push(next);
openList.push_back(next);
nod.child->accept(*this);
openList.pop_back();
};
There are a two main reasons why I am confused about this:
The two different constructors cause a different number of leaks
The leaks are reported to occur during visits
The accept methods of all nodes simply triggers a standard double dispatch to the visit method of the correct visitor.
I am fairly new to C++ programming and might have overlooked some really fundamental issue.
copyCreator<nodeType>::push(ptr) is supposed to take ownership of ptr. But it fails to do so if (a) ptr is not of type nodeType* (as determined by dynamic_cast), and (b) no node of type nodeType has been visited yet.
In other words, copyCreator<nodeType> creates, and promptly leaks, copies of all nodes until it encounters one of type nodeType.
This is precisely what happens in copyCreator<programNode> cpy2(&globalScope, a);, where a is forallNode*. cpy2 expects to encounter programNode (which it never does), and meanwhile, it copies and leaks all other nodes.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I had an exam and they asked about queues. I am wonder how a reverse method can be written without using any private part of the header file given. So the method must be written by using only public part of the file. Also you cannot create a new Queue, or delete the queue existing already. You cannot use inheritance, interface etc. Also the method is required to work in O(N) time complexity. It is too much required and I could not find a solution for it.
Header file is :
#include <iostream>
using namespace std;
class Queue
{
public:
Queue(); // Class constructor
~Queue(); // Class destuctor
void ClearQueue(); // Remove all items from the queue
bool Enqueue(int newItem); // Enter an item in the queue
int Dequeue(); // Remove an item from the queue
bool isEmpty(); // Return true if queue is empty
private:
struct Node(){
Node *next;
int item;
};
Node *front;
Node *back;
};
//and the prototype of the method wanted :
bool reverse(){
}
You could write a recursive function. Add the following function to your class:
bool reverse() {
if (this->isEmpty())
return true;
int value = this->Dequeue();
this->reverse();
this->Enqueue(value);
return true;
}
If you don't want the function to be a method of the class Queue and you have a global Queue-object queue, you could also write a global function like this:
bool reverse() {
if (queue.isEmpty())
return true;
int value = queue.Dequeue();
queue.reverse();
queue.Enqueue(value);
return true;
}
If you don't have a global Queue-object, you will have to pass the queue as parameter, see:
bool reverse(Queue& queue) {
if (queue.isEmpty())
return true;
int value = queue.Dequeue();
queue.reverse(queue);
queue.Enqueue(value);
return true;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I was trying to program my own List class on C++.
Here is the code:
template <class T>
class List
{
private:
T *value, *valueHelper;
int valueSize;
public:
int size;
List()
{
valueSize = 2;
value = new T[valueSize];
size = 0;
}
void Add(T val)
{
size++;
if (size > valueSize)
{
valueSize *= 2;
valueHelper = new T[valueSize];
memcpy(valueHelper, value, sizeof(T) * (size - 1));
delete[](value);
value = valueHelper;
}
value[size - 1] = val;
}
void Clear()
{
delete[](value);
size = 0;
valueSize = 2;
value = new T[valueSize];
}
T & operator[](int P)
{
return value[P];
}
};
The problem appered when I used a class variable on this List Class.
When I do Clear to delete some memory, there are a run time error appers.
I have trying to check what cause this problem and I have find out that this line on the function Clear() is the error line:
delete[](value);
I can not understand, why?
I'm just guessing here, but it could be likely it is because you will have copies made of the List instance, for example by returning it from a function or passing it as a non-reference argument to a function.
Copying of objects are implemented by the default copy-constructor generated by the compiler, but it only does shallow copying, meaning it will copy the pointers but not what they point to. So then you will have two copies with pointers pointing to the same memory, and when one object deletes that memory the others pointer will be invalid.
You also have a memory leak in that you don't have a destructor, so when an instance goes out of scope then you loose the allocated memory forever.
You should also read about the rule of three.
I'm new to this website and will try to contribute just as much as I ask. Also, please know I never ask a question without spending much time trying to figure it out myself.
As such, C++ Stacks are driving me f***ing crazy.
My Question: where do I place my variables/values in the Stack function block to actually use it. I understand Stacks are a LIFO data-structure, I've read countless examples of stacking plates on top of each other, etc.
Look at this code:
#include <iostream>
using namespace std;
const int MAX_SIZE = 100;
class StackOverFlowException
{
public:
StackOverFlowException()
{
cout << "Stack overflow" << endl;
}
};
class StackUnderFlowException
{
public:
StackUnderFlowException()
{
cout << "Stack underflow" << endl;
}
};
class ArrayStack
{
private:
int data[MAX_SIZE];
int top;
public:
ArrayStack()
{
top = -1;
}
void Push(int element)
{
if ( top >= MAX_SIZE )
{
throw new StackOverFlowException();
}
data[++top] = element;
}
int Pop()
{
if ( top == -1 )
{
throw new StackUnderFlowException();
}
return data[top--];
}
int Top()
{
return data[top];
}
int Size()
{
return top + 1;
}
bool isEmpty()
{
return ( top == -1 ) ? true : false;
}
};
[etc....]
It's basic cookie-cutter....let's say I'm trying to adapt it to express a system where the last food orders placed in, are kicked out first; variables are 'food', 'orders', and whatever else.
Where in the world am I integrating those variables into that stack code above!?!??!
Please help so confused i'm about to indiscriminately punch something
A stack implementation could use templates so that you could put whatever you want in the stack (within reason).
For example, have a class that encapsulates all the data related to orders (this one is just an example):
class FoodOrder
{
int orderNumber;
time_t orderTime;
// add more variables here
}
Then, your stack could look like this:
template<typename T> class Stack
{
T data[MAX_SIZE];
int top;
void Push(T item);
T Pop(void);
// add methods
}
Then, you could have a Stack of whatever items you want:
Stack<int> stackOfInts;
Stack<std::string> stackOfStrings;
Stack<FoodOrder> stackOfOrders;
Use the existing std::stack and wrap it if you want the exceptions, for example like this (note you could easily templatize it):
class protectedstack
{
private:
std::stack<int> stack;
const int myarbitraryupperlimit = 100;
public:
void pop()
{
if(stack.empty())
{
throw new StackUnderFlowException();
}
stack.pop();
}
void push(const int& value)
{
if(stack.size()>=myarbitraryupperlimit)
{
throw new StackOverFlowException();
}
stack.push(value);
}
// Similar for top/empty/constructors/...
};
The type of data, as well as that of what Top & Pop return, and what Push takes as an argument, is what is contained in the stack; that's what you'd replace w/ the type of whatever you want to make this a stack of.
This is a stack:
Think of it this way: the only way to add a book without moving the others is to place it on top : this is what Push does. So by calling Push(Book1), you'd be placing Book1 on top of the pile.
Similarly, the only way to take away a book without moving the others is to take the one on top : this is what Pop does. So by calling Pop(), you'd be getting (and removing from the stack) whichever book is on top of the stack, which in the image is the green book.
Am I missing something or was this your question?
It's all in the top variable. This variable dictates which object is the current top. When you pop(), then the top variable is reduced- meaning that the top is now one below where it was. When you push(), it's incremented- the top is now one above where it was. This variable is what accounts for the LIFO functionality of the stack.
You can, of course, template the class to make it work with a FoodOrder or whatever.
I don't see why the confusion. The data would go in, duh!, the "data" variable.
So, you either use Templates, to make the data buffer able to hold anything, or you change the type of the data to what you specifically need.
If for example you have a FoodOrder class, you can do it like this (my C++ is rusty, but this is basically the gist of it):
FoodOrder *data[MAX_SIZE];
You would have to change the push/pop parameters to accept a FoodOrder pointer/reference accordingly, and you're set.
P.S. About using std::stack --this might be a better solution, but doesn't answer his specific question.
P.S 2 Poster writes: "I'm new to this website and will try to contribute just as much as I ask.". Really? So why hasn't he even picked an answer yet? Does this smell more like a homework assignment?