我错过了什么,导致内存泄漏的原因C ++

时间:2018-06-17 18:02:19

标签: c++ class templates memory-management memory-leaks

我无法理解我的项目中的内存泄漏位置。 我构建的模板如下所示:

#pragma once
#include "IHeap.h"
#include <iostream>

using namespace std;

template <typename T>
class dHeap
{
public:
    dHeap(T size);
    dHeap(T size, int nr);
    dHeap(const dHeap &original);
    ~dHeap();
    dHeap<T>& operator=(const dHeap<T> &original);

    void deepCopy(const dHeap &original);
    void push(const T &item);
    T pop();
    T peek()const;
    int size()const;
    int getdValue()const;
    void printAll()const;

    void heapify(int arr[], int size, int root);
    void heapSort(int arr[], int size);

private:
    //T nr;
    T *arrHeap;
    T nrOfItems;
    T capacity;
    T dValue;

    void expandHeap();
};

template<typename T>
inline dHeap<T>::dHeap(T size)
{
    capacity = size;
    arrHeap = new T[capacity + 1];
    nrOfItems = 0;
    dValue = size;

}

template<typename T>
inline dHeap<T>::dHeap(T size, int nr)
{
    capacity = size;
    arrHeap = new T[nr];
    nrOfItems = 0;
    dValue = size;
}

template<typename T>
inline dHeap<T>::dHeap(const dHeap &original)
{
    this->deepCopy(original);
}

template<typename T>
inline dHeap<T>::~dHeap()
{
    delete[] arrHeap;
}

template<typename T>
inline dHeap<T>& dHeap<T>::operator=(const dHeap<T>& original)
{
    if (this != &original)
    {
        this->deepCopy(original);
    }
    return *this;
}

template<typename T>
inline void dHeap<T>::expandHeap()
{
    capacity *= 2;
    T *temp = new T[capacity];

    for (int i = 0; i < nrOfItems; i++)
    {
        temp[i] = arrHeap[i];
    }   

    delete[] arrHeap;
    arrHeap = temp;
}

template<typename T>
inline void dHeap<T>::deepCopy(const dHeap &original)
{
    capacity = original.capacity;
    nrOfItems = original.nrOfItems;
    arrHeap = new T[capacity];
    dValue = original.dValue;

    for (int i = 0; i < original.nrOfItems; i++)
    {
        this->arrHeap[i] = original.arrHeap[i];
    }
}

template<typename T>
inline void dHeap<T>::push(const T &item)
{
    if (nrOfItems >= capacity)
    {
        expandHeap();
    }

    arrHeap[nrOfItems] = item;
    nrOfItems++;
}

template<typename T>
inline T dHeap<T>::pop()
{
    int removed = arrHeap[0];
    arrHeap[0] = arrHeap[nrOfItems - 1];

    nrOfItems--;

    return removed;
}

template<typename T>
inline T dHeap<T>::peek() const
{
    return arrHeap[0];
}

template<typename T>
inline int dHeap<T>::size() const
{
    return this->nrOfItems;
}

template<typename T>
inline int dHeap<T>::getdValue() const
{
    return this->dValue;
}

template<typename T>
inline void dHeap<T>::printAll() const
{
    for (int i = 0; i < nrOfItems; i++)
    {
        cout << "Heap element " << i << ". " << arrHeap[i] << endl;
    }
}

template<typename T>
inline void dHeap<T>::heapSort(int arr[], int size)
{
    for (int j = 0; j < size; j++)
    {
        // Build heap - which means rearrange array
        for (int i = size / 2 - 1; i >= 0; i--)
        {
            heapify(arrHeap, size, i);
        }

        for (int i = size - 1; i >= 0; i--)
        {
            swap(arrHeap[0], arrHeap[i]);
            heapify(arrHeap, i, 0);
        }

        //when re-structured heap, use pop and re-do it again until done
        arr[j] = pop();
    }
}
template<typename T>
inline void dHeap<T>::heapify(int arr[], int n, int root)
{
    int largest = root;  
    int leftChild = 2 * root + 1;
    int rightChild = 2 * root + 2;

    // If left child is larger than root
    if (leftChild < n && arr[leftChild] > arr[largest])
    {
        largest = leftChild;
    }

    // If right child is larger than largest so far
    if (rightChild < n && arr[rightChild] > arr[largest])
    {
        largest = rightChild;
    }

    // If largest is not root, heapify recursivly until done
    if (largest != root)
    {
        swap(arr[root], arr[largest]);
        heapify(arr, n, largest);
    }
}

我有一个名为heapArr的指针,用于构建堆。当程序终止时,析构函数被调用,并且在程序完成时我有一个delete [] this-&gt; heapArr声明来删除指针。 我还在expand函数中添加了delete [] this-&gt; heapArr,以便在分配新的扩展数组之前释放内存。

我不确定我是否完美地解释了这个问题但问题是我似乎错过了删除某些东西,因为当我结束程序时我收到了内存泄漏警告。 我错过了什么?

1 个答案:

答案 0 :(得分:1)

deepCopy中的内存泄漏,您可以在其中分配新内存而无需取消分配旧内存。

话虽如此,不要自己分配内存。很大一部分代码都会复制std::vector的功能,因此请使用std::vector<T>代替T*(如果由于某种原因你不能使用std::vector我会建议你实现一个替换。通过从堆逻辑中分离内存管理来分而治之。)