不释放内部单元格时泄漏内存?
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
个对象的 all。 delete[]
销毁数组中的 所有 对象,并释放整个数组。因此,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)。它尝试将其他 set
s 数据分配给该临时值 (2)。如果失败,必须删除 temp
(3) 否则我们可以用存储在 temp_data
中的新数据替换旧的 data
并且在此之前我们必须删除旧数据 ( 4).
try
块中没有分配。函数中分配的所有内存要么被删除(当分配失败时),要么用于替换旧数据,在这种情况下旧的data
被删除。
如果 data
是一个数组而不是单个 int
(几乎)没有任何变化,也没有泄漏。您担心的元素已经分配在 T* data_temp = new T[set.size];
行中,然后 delete[] temp_data;
将删除所有这些元素。
我的教授写了以下代码:
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 deletingtemp_data
, but what about the values of the first 3 cells intemp_data
which were allocated insideoperator=
code? we aren't freeing them.
new[]
分配整个数组并构造其中 T
个对象的 all。 delete[]
销毁数组中的 所有 对象,并释放整个数组。因此,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)。它尝试将其他 set
s 数据分配给该临时值 (2)。如果失败,必须删除 temp
(3) 否则我们可以用存储在 temp_data
中的新数据替换旧的 data
并且在此之前我们必须删除旧数据 ( 4).
try
块中没有分配。函数中分配的所有内存要么被删除(当分配失败时),要么用于替换旧数据,在这种情况下旧的data
被删除。
如果 data
是一个数组而不是单个 int
(几乎)没有任何变化,也没有泄漏。您担心的元素已经分配在 T* data_temp = new T[set.size];
行中,然后 delete[] temp_data;
将删除所有这些元素。