0

以下の 3 つの関数には、Dr. Memory によると、「// メモリ リーク vvv」とマークされた行にメモリ リークが含まれています。私は C++ とポインターに比較的慣れていないため、これらの行がリークを引き起こしている理由がわかりません。「values_」は T** であり、UndoArray クラスのメンバー変数です。

template <class T> void UndoArray<T>::set(size_type i, const T& v) {
    counts_[i]++;
    if(!initialized(i)) {
        // memory leak vvv
        values_[i] = new T[1];
        values_[i][0] = v;
    } else {
        // memory leak vvv
        T* temp = new T[counts_[i]];
        for(int j = 0; j < counts_[i] - 1; j++) {
            temp[j] = values_[i][j];
        }
        temp[counts_[i] - 1] = v;
        delete [] values_[i];
        values_[i] = temp;
    }
}

template <class T> void UndoArray<T>::undo(size_type i) {
    counts_[i]--;
    if(counts_[i] == 0) {
        values_[i] = NULL;
    } else {
        T* temp = values_[i];
        // memory leak vvv
        values_[i] = new T[counts_[i]];
        for(int j = 0; j < counts_[i]; j++) {
            values_[i][j] = temp[j];
        }
        delete [] temp;
    }
}

template <class T> void UndoArray<T>::copy(const UndoArray<T>& ua) {
    size_ = ua.size_;
    counts_ = new unsigned[size_];
    for(int i = 0; i < size_; i++) {
        counts_[i] = ua.counts_[i];
    }
    values_ = new T*[size_];
    for(int i = 0; i < size_; i++) {
        if(counts_[i] == 0) {
            values_[i] = NULL;
        } else {
            // memory leak vvv
            values_[i] = new T[counts_[i]];
            for(int j = 0; j < counts_[i]; j++) {
                values_[i][j] = ua.values_[i][j];
            }
        }
    }
}

UndoArray のコンストラクタは...

template <class T> void UndoArray<T>::create() {
    size_ = 0;
    counts_ = new unsigned[size_];
    values_ = new T*[size_];
}

... デフォルトのコンストラクターが呼び出された場合 (引数なし) または ...

template <class T> void UndoArray<T>::create(size_type n) {
    size_ = n;
    counts_ = new unsigned[size_];
    for(int i = 0; i < size_; i++)
        counts_[i] = 0;
    values_ = new T*[size_];
    for(int i = 0; i < size_; i++)
        values_[i] = NULL;
}

...初期配列サイズが指定されている場合。

デストラクタは次のようになります...

template <class T> UndoArray<T>::~UndoArray() {
    delete [] counts_;
    if(values_ != NULL) {
        for(int i = 0; i < size_; i++) {
            delete [] values_[i];
        }
    }
    delete [] values_;
}
4

2 に答える 2

0
template <class T> void UndoArray<T>::set(size_type i, const T& v) {
    counts_[i]++;
    if(!initialized(i)) {
        // memory leak vvv`

values_[i] は削除されないため、これはリークです。

    values_[i] = new T[1];
    values_[i][0] = v;
} else {
    // memory leak vvv

ここで同じ問題。一時削除はありません。声明。

    T* temp = new T[counts_[i]];
    for(int j = 0; j < counts_[i] - 1; j++) {
        temp[j] = values_[i][j];
    }
    temp[counts_[i] - 1] = v;
    delete [] values_[i];
    values_[i] = temp;
}

新しいメモリに対して delete を呼び出す必要があります。クラスのデストラクタが values_ をクリーンアップしない限り。

于 2013-09-24T18:52:19.347 に答える