gpt4 book ai didi

c++ - 动态数组释放(赋值运算符与复制构造函数)

转载 作者:太空宇宙 更新时间:2023-11-04 14:09:12 25 4
gpt4 key购买 nike

我应该在复制构造函数和/或赋值运算符中释放动态数组(在构造函数中分配)吗?

struct Test
{
const size_t n;
int* xs;

Test(const size_t n)
: n(n)
, xs(new int[n])
{ }

Test(const Test& other)
: n(other.n)
, xs(new int[n])
{
memcpy(xs, other.xs, n * sizeof(int));
}

Test& operator=(const Test& other)
{
n = other.n;
delete[] xs;
xs = new int[n];
memcpy(xs, other.xs, n * sizeof(int));
}

~Test()
{
delete[] xs;
}
};

void main()
{
Test a(10);
Test b(a);
Test c(20);
c = b;
}

如您所见,我猜您必须在赋值运算符实现中delete[] 数组(因为它已经在构造被赋值对象的过程中分配到某处)。而且我确实认为您不需要在复制构造对象时释放数组,因为它还没有被构造。

事实是,无论 operator= 中是否有 delete[],在 Application Verifier 下运行上面的应用程序都不会显示内存泄漏。尽管在这两种情况下应用程序运行正常。

那么,我应该在复制构造函数和赋值运算符中删除[] xs,还是两者都删除?

最佳答案

一般来说,手动内存管理是一个的主意。你不应该这样做,你应该更喜欢std::vector<>或其他容器类,除非您有充分的理由不这样做。这说...

So, should I delete[] xs in copy constructor, assignment operator, both or neither?

你应该delete[]new[] 分配的数组在丢失指向该数组的最后一个指针之前。否则,你会泄漏。

实际上,由于您要删除的数组由您的类拥有和封装,这意味着您必须 delete[]它在赋值运算符重载中(在指针被分配给一个新数组之前,因此丢失了对前一个数组的唯一现有引用)和析构函数中(当您处理对象然后丢失对封装的唯一现有引用时大批)。

正如你所说,复制构造函数是一个构造例程,指针之前没有引用任何分配的资源(事实上,这里没有“之前”,对象的生命周期甚至还没有开始):因此,它不仅不需要delete[]在这里,它是错误的。

另请注意,为了避免悬挂指针和可能的未定义行为,您应该确保您的类确实是封装数组的唯一所有者。否则,类外部的代码可能 delete[]它,或者保存指向它的指针,这将变得悬空。因此,你不应该制作 xs数据成员public .

关于c++ - 动态数组释放(赋值运算符与复制构造函数),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15567907/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com