template<typename T>
struct Block
{
T val;
Block* top;
};
template<typename T>
class GStack
{
public:
Block<T>* base;
int blocks = 0;
public:
GStack(const T& firstVal) : base{ new Block<T>{ firstVal, nullptr } }
{
blocks++;
}
~GStack()
{
ClearAll();
base = nullptr;
}
// Deletes all the blocks from the stack
void ClearAll()
{
for (int i{ 0 }; i < blocks; i++)
{
std::cout << "ClearAll()" << endl;
pop();
}
}
void push(const T& val)
{
Block<T>* newBlock = new Block<T>;
newBlock->val = val;
newBlock->top = nullptr;
if (!base)
base = newBlock;
else
{
Block<T>* tmp = base;
while (tmp->top)
{
tmp = tmp->top;
}
tmp->top = newBlock;
}
blocks++;
}
void pop()
{
if (blocks > 0)
{
Block<T>* previous = base;
Block<T>* tmp = previous->top;
if (tmp)
{
// Make tmp to point to the last block
while (tmp->top)
{
tmp = tmp->top;
previous = previous->top;
}
delete tmp;
tmp = nullptr;
previous->top = nullptr;
}
// If it's the last block...
else
{
delete previous;
previous = nullptr;
// set the base block point to nothing
base = nullptr;
}
blocks--;
}
}
In the main, if I write
1 2 3 4 5
GStack<int>* my{ new GStack<int>{0} };
my->push(10);
my->push(20);
my->push(30);
my->ClearAll();
The output is:
ClearAll()
ClearAll()
Hmh... bug!
It should be printed out 4 times, since the blocks are 4!
I tested that and, if you try to remove the pop() function call form the ClearAll() function in the for loop... then the ClearAll() gets called four times.
But why?
What's happening behind the scenes?
NOTE
For some reason the bug is related to the for loop in the ClearAll() function, specifically with the blocks variable which counts the number of blocks (nodes) in the stack.
Notice that Blocks is being decremented in the pop function. And in ClearAll(), the loop statement will check if i < blocks and after 2 iterations, blocks = 2 and i =2. The loop end there.