不释放内部单元格时泄漏内存?

Leaking memory when not freeing internal cells?

我的教授写了以下代码:

template <class T>
Set<T>& Set<T>::operator=(const Set<T>& set) {
  if (this == &set) return *this;
  T* data_temp = new T[set.size];
  try {
    for (int i = 0; i < size; ++i) {
      temp_data[i] = set.data[i];
    }
  } catch (...) {
    delete[] temp_data;
    throw;
  }
  delete[] data;
  data = temp_data;
  size = maxSize = set.size;
  return *this;
}

他指出 temp_data[i] = set.data[I]; 调用 operator=,我想知道为什么这不会泄漏内存?

例如,如果 operator= 在第 4 次循环中失败,那么我们将删除 temp_data,但是 temp_data 中分配在 [= 中的前 3 个单元格的值呢? 12=]代码?我们不会释放他们。

For example if operator= failed in the 4th loop then we are deleting temp_data, but what about the values of the first 3 cells in temp_data which were allocated inside operator= code? we aren't freeing them.

在到达循环之前,

new[] 分配整个数组并构造其中 T 个对象的 alldelete[] 销毁数组中的 所有 对象,并释放整个数组。因此,T 的构造函数和析构函数有责任正确初始化和完成 T 的数据成员。

循环仅更新数组中对象的数据成员的内容T::operator= 有责任根据需要正确复制和释放 T 的数据成员。

Set::operator= 代码中没有泄漏。但是有一个小错误 - 循环需要使用 set.size 而不是 size.

for (int i = 0; i < set.size; ++i)

新数组分配了 set.size 个元素,这就是循环需要复制的元素数量。

对循环使用size,如果分配给Set小于被复制的Set,新数组将不会复制所有元素。如果分配给更大的 Set,循环将超出两个数组的范围。

如果您遇到泄漏,它必须在 T::operator=T::~T() 中,您都没有显示。假设 Set::Set()Set::~Set() 正在正确初始化和释放 data,这是。

让我们从这段代码中删除一些复杂的东西。让我们假设 T == int 而不是存储许多 int 我们只存储一个:

int_store& int_store::operator=(const int_store& set)
{
    int* temp_data = new int;   (1) allocate
    try 
    {
        *temp_data = *set.data;   (2) assign
    }
    catch (...) 
    {
        delete temp_data;       (3) free temp
        throw;
    }
    delete data;                (4) free old 
    data = temp_data;
}

该方法有一个分配 int* temp_data = new int (1)。它尝试将其他 sets 数据分配给该临时值 (2)。如果失败,必须删除 temp (3) 否则我们可以用存储在 temp_data 中的新数据替换旧的 data 并且在此之前我们必须删除旧数据 ( 4).

try 块中没有分配。函数中分配的所有内存要么被删除(当分配失败时),要么用于替换旧数据,在这种情况下旧的data被删除。

如果 data 是一个数组而不是单个 int (几乎)没有任何变化,也没有泄漏。您担心的元素已经分配在 T* data_temp = new T[set.size]; 行中,然后 delete[] temp_data; 将删除所有这些元素。