I hope you all are doing great.
I have the following class that implements a stack of stacks and it's supposed to create a stack and once this stack has reached max capacity, it creates another and so on. The push() and pop() operations common to the stack data structure should operate as if it were a single stack. The Stack
class is a simple implementation of a stack data structure that has been working fine so far. The method pop_at
is used for popping an element from a specific stack.
The thing is, I've attempted to free up the dynamically allocated memory in the destructor, but I am certain that my code has more holes than Swiss cheese and memory is probably leaking. Is there an efficient way to check if the code is leaking memory? Also, what is the approach you guys take for making sure that everything is correct in this aspect?
Thanks everyone, have a good weekend!
class SetOfStacks
{
private:
std::unordered_map<int, Stack<int> *> all_stacks;
int max_capacity;
int stack_index;
int stack_count;
public:
void push(int plate_number)
{
Stack<int> *current_stack = all_stacks[this->stack_index];
if (current_stack->getSize() < this->max_capacity)
{
current_stack->push(plate_number);
return;
}
++this->stack_count;
++this->stack_index;
Stack<int> *new_stack = new Stack<int>();
new_stack->push(plate_number);
all_stacks[stack_index] = new_stack;
}
void pop(void)
{
Stack<int> *current_stack = all_stacks[this->stack_index];
if (current_stack->getSize() > 0)
{
current_stack->pop();
}
if (current_stack->getSize() == 0)
{
all_stacks.erase(this->stack_index);
--this->stack_index;
--this->stack_count;
}
}
int peek(void)
{
Stack<int> *current_stack = all_stacks[this->stack_index];
return current_stack->peek();
}
void pop_at(int stack_id)
{
if ((stack_id < this->stack_count) && (stack_id >= 0))
{
this->all_stacks[stack_id]->pop();
}
else
{
std::cout << "Stacks IDs go from 0 to " << (this->stack_count - 1) << "\n";
}
}
int how_many_stacks(void)
{
return this->stack_count;
}
int stack_occupancy(void)
{
return this->all_stacks[this->stack_index]->getSize();
}
int which_stack(void)
{
return this->stack_index;
}
SetOfStacks(int capacity)
{
this->max_capacity = capacity; // total capacity for the stacks
this->stack_index = 0; // initial stack
this->stack_count = 1; // we begin with only 1 stack of size max_capacity
all_stacks[this->stack_index] = new Stack<int>(); // add initial stack to the table
}
~SetOfStacks()
{
auto it = all_stacks.begin();
while (it != all_stacks.end())
{
auto stack_ptr = it->second;
delete stack_ptr;
stack_ptr = nullptr;
++it;
}
}
};
main function:
int main()
{
SetOfStacks *st = new SetOfStacks(5);
for (int i{0}; i < 12; ++i)
{
st->push(i);
}
// stack: [0 1 2 3 4] [5 6 7 8 9] [10 11]
std::cout << "Num. of stacks: " << st->how_many_stacks() << "\n"
<< "Current stack: " << st->which_stack() << "\n"
<< "Stack occupancy: " << st->stack_occupancy() << "\n"
<< "Top: " << st->peek() << "\n-----\n";
for (int i{0}; i < 6; ++i)
{
st->pop();
}
// stack: [0 1 2 3 4] [5]
std::cout << "Num. of stacks: " << st->how_many_stacks() << "\n"
<< "Current stack: " << st->which_stack() << "\n"
<< "Stack occupancy: " << st->stack_occupancy() << "\n"
<< "Top: " << st->peek() << "\n-----\n";
st->pop();
st->pop_at(0);
// stack: [0 1 2 3]
std::cout << "Num. of stacks: " << st->how_many_stacks() << "\n"
<< "Current stack: " << st->which_stack() << "\n"
<< "Stack occupancy: " << st->stack_occupancy() << "\n"
<< "Top: " << st->peek() << "\n-----\n";
st->pop_at(3);
delete st;
return 0;
}