根据Dr. Memory的说法,下面的三个函数在标有“// memory leak 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_;
}
答案 0 :(得分:2)
代码中有几件不合适的东西:
即
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];
}
//What if values_ is not null here? You do not delete the old data
values_ = new T*[size_];
在您发布的代码中,您可以执行类似的操作。
Edit1:给你另一个例子
template <class T> void UndoArray<T>::undo(size_type i) {
counts_[i]--;
if(counts_[i] == 0) {
//what if values_[i] != nullptr here? You will leak the old value...
values_[i] = NULL;
当然,您应该确保删除析构函数中的每个指针。
像:
~UndoArray()
{
if (nullptr != values_)
{
for (int i = 0; i < size_; ++i)
{
delete [] values[i];
}
delete [] values;
}
}
答案 1 :(得分: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。除非类的析构函数清除值_。