Search code examples
c++templatesdelete-operator

How to delete a template?


I'm having trouble with deleting my template.
My template and destructor:

template<class S, class T>  
class Consortium
{

private :

    map<const S, Node<T>*> m_consortiumMap;
    Heap<T>m_consortiumHeap;

public :

    ~Consortium();
    void Insert(const S key, T toAdd);
    void Update(const S key);
    void Remove(const S key);
    const T Top();
};

template<class S, class T>
Consortium<S,T>::~Consortium()
{
    m_consortiumMap.clear();
    delete &m_consortiumHeap.;
}

My heap and destructor:

template <class T>
class Heap
{
private :

    vector<Node<T>*> m_heapVector;

public :

    ~Heap();

    int parent(int i) const {return i / 2;}
    int left(int i) const {return 2 * i;}
    int right(int i) const {return 2 * i + 1;}
    void heapify(int index);
    Node<T>* extractMin ();
    void heapDecreaseKey (int index, Node<T>* key);
    void MinHeapInsert (Node<T>* key);
    Node<T>* ExtractNode(int index);
    Node<T>* top ()const {return m_heapVector[0];}

};  

template<class T>
Heap<T>::~Heap()
{
    for (int i = 0 ; i < m_heapVector.size() ; i++)
        m_heapVector.erase(m_heapVector.begin() + i);
}

and this is the object that holds the template, I'm having problems with that also:

class Garage
{
    private :

        Consortium<string, Vehicle*> m_consortium;

    public :

        ~Garage() {delete &m_consortium;}
};

what's wrong here?


Solution

  • This is wrong on its face:

    delete &m_consortiumHeap;
    

    You must only delete things that you allocated with new. m_consortiumHeap is part of the class and gets automatically allocated when the class gets allocated and automatically deallocated when the class gets deallocated. You cannot and must not explicitly delete it.

    This may have the opposite problem:

    m_consortiumMap.clear();
    

    the contents of m_consortiumMap are pointers. I can't tell from the code you've shown, but if the nodes within the map are allocated by the Consortium class using new, they must be deleteed, otherwise you will leak memory. Clearing the map will only get rid of the pointers, it will not deallocate the memory that they point to. You must first iterate through the map and delete each element. While deallocation of the elements is important, clearing the map in the destructor is kind of pointless since the map itself will be destroyed immediately afterwards anyway.

    This is just perplexing:

    for (int i = 0 ; i < m_heapVector.size() ; i++)
        m_heapVector.erase(m_heapVector.begin() + i);
    

    first of all, everything I said about m_consortiumMap applies also to m_heapVector: If the contents were allocated with new by the Heap class, you must delete them in the destructor. And erasing the pointers from the vector is pointless, not to mention that the above loop has a logic error in it. When you iterate over a container, you should use the iterators themselves, e.g.

    for (std::vector<Node<T>*>::iterator i = m_heapVector.begin() ; i != m_heapVector.end() ; i++)
    

    Also, std::vector, like std::map, has a clear() function, but like I said it's pointless to clear the vector in the destructor. What you really want to do is deallocate the elements (if necessary).