0

I am trying to implement a stack using a set of sub-stacks of fixed length. For the sub-stack, I use a simple array of fixed length initialized in the constructor. For the stack, I use a vector of sub-stacks.

The below push method tries to allocate memory to a new substack and push it to the vector. But whenever a new push happens (let's say on vector setofstacks[1], the previous setofstacks[0] gets garbage values by the substack destructor being called. Not sure why this happens.

vector<substack<T>> setofstacks;

substack<T> *s = new substack<T>(size);
setofstacks.push_back(*s);
setofstacks[currStackIndex].push(elem);

On the other hand, if I convert the object to object pointer of substack and store that in the vector, that works perfectly well.

vector<substack<T>*> setofstacks;

setofstacks.push_back(new substack<T>(size));
setofstacks[currStackIndex]->push(elem);

Not working full code

/*  Program: Implement a stack of substacks of fixed size
*
*   Date: 12/28/2015
*/

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class substack
{
private:
    T *arr;
    int nextAvailable;
    int size;
public:
    substack(int capacity);
    ~substack();
    void push(T elem);
    T pop();
    T peek();
    bool isfull();
    bool isempty();
};

// Constructor initializing size of substack
template <class T>
substack<T>::substack(int capacity)
{
    nextAvailable = 0;
    size = capacity;
    arr = new T[capacity];
}

// Destructor freeing memory allocated by the stack implemented using array
template <class T>
substack<T>::~substack()
{
    delete[] arr;
    arr = NULL;
}

// Pushing an element on top of a substack of fixed size
template <class T>
void substack<T>::push(T elem)
{
    if (nextAvailable < size)
    {
        arr[nextAvailable] = elem;
        nextAvailable++;
    }
    else
    {
        cout << "Substack is full" << endl;
        return;
    }
}

// Popping the top element from a stack of fixed size
template <class T>
T substack<T>::pop()
{
    nextAvailable--;

    if (nextAvailable >= 0)
    {
        T del = arr[nextAvailable];
        arr[nextAvailable] = NULL;
        return del;
    }
    else
    {
        cout << "Stack is empty" << endl;
        return NULL;
    }
}

// Peeking the top element from a stack of fixed size
template <class T>
T substack<T>::peek()
{
    if (nextAvailable > 0)
    {
        return arr[nextAvailable - 1];
    }
    else
    {
        cout << "Stack is empty" << endl;
        return NULL;
    }
}

// Checking if a substack is full or not
template <class T>
bool substack<T>::isfull()
{
    return (nextAvailable == size);
}

// Checking if a substack is empty or not
template <class T>
bool substack<T>::isempty()
{
    return (nextAvailable == 0);
}

template <class T>
class SetOfStacks
{
private:
    //vector<substack<T>*> setofstacks;
    vector<substack<T>> setofstacks;
    int currStackIndex;
    int size;
public:
    SetOfStacks(int capacity);
    ~SetOfStacks();
    void push(T elem);
    T pop();
    T peek();
};

// Constructor initializing a set of stacks
template <class T>
SetOfStacks<T>::SetOfStacks(int maxStackCapacity)
{
    currStackIndex = 0;
    size = maxStackCapacity;
    substack<T> *s = new substack<T>(maxStackCapacity);
    setofstacks.push_back(*s);
    //setofstacks.push_back(new substack<T>(maxStackCapacity));
}

// Destructor clearing set of stacks vector
template <class T>
SetOfStacks<T>::~SetOfStacks()
{
    setofstacks.clear();
}

// Pushing an element on top of a stack implemented by a set of fixed length substacks
    template <class T>
    void SetOfStacks<T>::push(T elem)
    {
        if (!setofstacks[currStackIndex].isfull())
        {
            setofstacks[currStackIndex].push(elem);
        }
        else
        {
            currStackIndex++;
            substack<T> *s = new substack<T>(size);
            setofstacks.push_back(*s);
            //setofstacks.push_back(new substack<T>(size));
            setofstacks[currStackIndex].push(elem);
        }
    }

// Popping an element from top of a stack implemented by a set of fixed length substacks
template <class T>
T SetOfStacks<T>::pop()
{
    if (!setofstacks[currStackIndex].isempty())
    {
        return setofstacks[currStackIndex].pop();
    }
    else
    {
        setofstacks.pop_back();
        currStackIndex--;

        if (currStackIndex >= 0)
        {
            return setofstacks[currStackIndex].pop();
        }
        else
        {
            cout << "Stack is empty" << endl;
            return NULL;
        }
    }
}

// Peeking an element from top of a stack implemented by a set of fixed length substacks
template <class T>
T SetOfStacks<T>::peek()
{
    return setofstacks[currStackIndex].peek();
}

int main()
{
    SetOfStacks<int> *s = new SetOfStacks<int>(5);
    s->push(1);
    s->push(2);
    s->push(3);
    s->push(4);
    s->push(5);

    s->push(6);
    s->push(7);
    s->push(8);

    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;

    s->push(1);
    s->push(2);
    s->push(3);

    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    //cout << s->pop() << endl;

    system("pause");
}

Output

8
7
6
-572662307
-572662307
-572662307
-572662307
-572662307
3
2
1
Press any key to continue . . .

Working Code

/*  Program: Implement a stack of substacks of fixed size
*
*   Date: 12/28/2015
*/

#include <iostream>
#include <vector>

using namespace std;

template <class T>
class substack
{
private:
    T *arr;
    int nextAvailable;
    int size;
public:
    substack(int capacity);
    ~substack();
    void push(T elem);
    T pop();
    T peek();
    bool isfull();
    bool isempty();
};

// Constructor initializing size of substack
template <class T>
substack<T>::substack(int capacity)
{
    nextAvailable = 0;
    size = capacity;
    arr = new T[capacity];
}

// Destructor freeing memory allocated by the stack implemented using array
template <class T>
substack<T>::~substack()
{
    delete[] arr;
    arr = NULL;
}

// Pushing an element on top of a substack of fixed size
template <class T>
void substack<T>::push(T elem)
{
    if (nextAvailable < size)
    {
        arr[nextAvailable] = elem;
        nextAvailable++;
    }
    else
    {
        cout << "Substack is full" << endl;
        return;
    }
}

// Popping the top element from a stack of fixed size
template <class T>
T substack<T>::pop()
{
    nextAvailable--;

    if (nextAvailable >= 0)
    {
        T del = arr[nextAvailable];
        arr[nextAvailable] = NULL;
        return del;
    }
    else
    {
        cout << "Stack is empty" << endl;
        return NULL;
    }
}

// Peeking the top element from a stack of fixed size
template <class T>
T substack<T>::peek()
{
    if (nextAvailable > 0)
    {
        return arr[nextAvailable - 1];
    }
    else
    {
        cout << "Stack is empty" << endl;
        return NULL;
    }
}

// Checking if a substack is full or not
template <class T>
bool substack<T>::isfull()
{
    return (nextAvailable == size);
}

// Checking if a substack is empty or not
template <class T>
bool substack<T>::isempty()
{
    return (nextAvailable == 0);
}

template <class T>
class SetOfStacks
{
private:
    vector<substack<T>*> setofstacks;
    int currStackIndex;
    int size;
public:
    SetOfStacks(int capacity);
    ~SetOfStacks();
    void push(T elem);
    T pop();
    T peek();
};

// Constructor initializing a set of stacks
template <class T>
SetOfStacks<T>::SetOfStacks(int maxStackCapacity)
{
    currStackIndex = 0;
    size = maxStackCapacity;
    //substack<T> *s = new substack<T>(maxStackCapacity);
    setofstacks.push_back(new substack<T>(maxStackCapacity));
}

// Destructor clearing set of stacks vector
template <class T>
SetOfStacks<T>::~SetOfStacks()
{
    setofstacks.clear();
}

// Pushing an element on top of a stack implemented by a set of fixed length substacks
template <class T>
void SetOfStacks<T>::push(T elem)
{
    if (!setofstacks[currStackIndex]->isfull())
    {
        setofstacks[currStackIndex]->push(elem);
    }
    else
    {
        currStackIndex++;
        //substack<T> *s = new substack<T>(size);
        setofstacks.push_back(new substack<T>(size));
        setofstacks[currStackIndex]->push(elem);
    }
}

// Popping an element from top of a stack implemented by a set of fixed length substacks
template <class T>
T SetOfStacks<T>::pop()
{
    if (!setofstacks[currStackIndex]->isempty())
    {
        return setofstacks[currStackIndex]->pop();
    }
    else
    {
        setofstacks.pop_back();
        currStackIndex--;

        if (currStackIndex >= 0)
        {
            return setofstacks[currStackIndex]->pop();
        }
        else
        {
            cout << "Stack is empty" << endl;
            return NULL;
        }
    }
}

// Peeking an element from top of a stack implemented by a set of fixed length substacks
template <class T>
T SetOfStacks<T>::peek()
{
    return setofstacks[currStackIndex].peek();
}

int main()
{
    SetOfStacks<int> *s = new SetOfStacks<int>(5);
    s->push(1);
    s->push(2);
    s->push(3);
    s->push(4);
    s->push(5);

    s->push(6);
    s->push(7);
    s->push(8);

    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;

    s->push(1);
    s->push(2);
    s->push(3);

    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;
    cout << s->pop() << endl;

    system("pause");
}

Output

8
7
6
5
4
3
2
1
3
2
1
Stack is empty
0
Press any key to continue . . .

Please let me know what I am missing about using push_back while adding actual substack object so that it does not mess up the previous index substack in the vector.

Not sure how is this a dupe of rule of three. Am I missing one of the three - copy constructor, assignment operator? Please help me understand.

Ankit
  • 115
  • 10
  • @juanchpanza: I am fairly new to C++. Can you please help me understand how this is related to the question you duped on? – Ankit Dec 29 '15 at 08:24
  • 1
    I really think this question should be reopened. The user has a specific problemen and he or she doesn't understand what's causing it. The "rule of three" might be a step to far and needs explanation in context to this question. (Voted to reopen). – Rolf ツ Dec 29 '15 at 08:36
  • Thanks @Rolf. Really appreciate it. – Ankit Dec 29 '15 at 16:57

0 Answers0