C++ C++;2d数组指针内存泄漏

C++ C++;2d数组指针内存泄漏,c++,pointers,memory,memory-leaks,delete-operator,C++,Pointers,Memory,Memory Leaks,Delete Operator,根据Dr.memory,以下三个功能在标有“//memory leak vvv”的行中包含内存泄漏。我对C++和指针比较陌生,不确定为什么这些行会导致泄漏。“values_u2;”是一个T**,是UndoArray类的成员变量 template <class T> void UndoArray<T>::set(size_type i, const T& v) { counts_[i]++; if(!initialized(i)) {

根据Dr.memory,以下三个功能在标有“//memory leak vvv”的行中包含内存泄漏。我对C++和指针比较陌生,不确定为什么这些行会导致泄漏。“values_u2;”是一个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];
            }
        }
    }
}
template void undo数组::set(大小\类型i,常量T&v){
计数_i]++;
如果(!初始化(i)){
//内存泄漏
值_i]=新的T[1];
值_i[0]=v;
}否则{
//内存泄漏
T*temp=新的T[counts_ui]];
对于(int j=0;j
UndoArray的构造函数使用

template <class T> void UndoArray<T>::create() {
    size_ = 0;
    counts_ = new unsigned[size_];
    values_ = new T*[size_];
}
template void UndoArray::create(){
尺寸=0;
计数=新的无符号[大小];
值=新的T*[尺寸];
}
。。。如果调用默认构造函数(无参数)或

模板数组::创建(大小\u类型n){
尺寸=n;
计数=新的无符号[大小];
对于(int i=0;i
。。。如果指定了初始数组大小

析构函数看起来像

template <class T> UndoArray<T>::~UndoArray() {
    delete [] counts_;
    if(values_ != NULL) {
        for(int i = 0; i < size_; i++) {
            delete [] values_[i];
        }
    }
    delete [] values_;
}
模板UndoArray::~UndoArray(){
删除[]个计数;
如果(值为空){
对于(int i=0;i
这里也有同样的问题。没有删除临时文件;声明

    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;
}
T*temp=newt[counts_ui]];
对于(int j=0;j

您必须对新内存调用delete。除非类的析构函数清除值.

否则代码中有几项不正常:

template void UndoArray::copy(const UndoArray&ua){
尺寸=ua.size;
计数=新的无符号[大小];
对于(int i=0;i
在你发布的代码中还有一些类似的情况

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;
模板void UndoArray::undo(大小\类型i){
计数(i);
如果(计数_i)==0){
//如果这里的值_[i]!=nullptr怎么办?您将泄漏旧值。。。
值_i]=NULL;
当然,您应该确保删除析构函数中的每个指针

比如:

~UndoArray()
{
if(nullptr!=值)
{
对于(int i=0;i
UndoArray的析构函数是什么样子的?@ZacHowland我编辑了我原来的问题,添加了构造函数。不是构造函数…析构函数。也就是说,当你的类被销毁时调用的方法,用来清理它的资源。他复制
值\u I[I]
temp
并删除
temp
。不在::set方法中。在::undo方法中,是的。他在set方法中也有一个
delete[]values\u i[i]
。类的析构函数现在会清理值。现在,当我尝试
values[i]=new T T[1]时,我唯一的漏洞在set函数中
@rileyberton:对于第二次分配(在else条件下),我的意思是。我显然错误地假设
初始化(I)
测试
值是否为I[I]
block已分配。我缺少删除值中的每个指针,例如您在析构函数中提到的for循环。在我添加后,唯一的泄漏是在set函数中,我尝试
values\ui]=new T[1]
。请注意,您应该修改您在其中一次编辑中发布的创建方法。您基本上是在分配一个零大小的数组。我不会详细介绍,但您可能应该阅读以下内容:If
values_I[I]
有一个分配的内存块连接到它,它将泄漏到那里。你需要测试它,删除那里的内容,然后你可以为它分配一个新的内存块。请参阅上面两个其他示例,其中可能是你应该删除分配的内存。我看到至少还有一个这样的丢失删除的示例。我认为你将继续如果您必须在UndoArray类实现中执行这种类型的内存管理,那么您可能会遇到麻烦。可能最好使用简单清晰的接口将values_uuu内容封装在一个单独的类中,并在单个位置执行内存管理…可能您可以用std::vector*values替换values_uu_
    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>::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_];
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;
  }
}