为什么在此复制分配 ctor 结束时没有释放获取的资源?

Why isn't the acquired resource released at the end of this copy assignment ctor?

本文关键字:释放 获取 资源 复制 分配 结束 ctor 为什么      更新时间:2023-10-16

我正在阅读C++编程语言第4版,我到达了有关复制赋值构造函数的部分。作者有一个名为 Vector 的类,他像这样定义复制赋值构造函数

Vector& Vector::operator=(const Vector& a)
{
   double* p = new double[a.sz];
   for (int i=0; i != a.sz; ++i)
      p[i] = a.elem[i];
   delete[] elem;
   elem = p;
   sz = a.sz;
   return *this
}

(对于那些拥有这本书的人,可以在第74页找到(现在,我的问题是:如果 p 有新资源,为什么在返回之前不发布删除?或者换一种说法:为什么缺少 delete[] p 不被视为内存泄漏?

问这个是因为,到目前为止,我注意到对于每个新内容都必须删除,而我看到的问题说"我应该在此处使用删除吗",指出对于每个新内容,都应该删除我看到这个问题 新的必须总是跟着删除吗?但在这种情况下,程序完成并释放资源,而在上面的代码中,程序继续。

(另外,还有一个附带的问题,elem = p 语句会调用复制赋值构造函数吗?这一行让我感到困惑,因为它似乎会调用它并执行一种无限循环(

对于执行的每个new,应该在某个地方执行一个delete。它不一定具有相同的功能。此外,程序文本中出现的一次delete可能与几种不同的new匹配,反之亦然。执行计数必须匹配,而不是文本匹配。

elem = p什么都没叫。 elemp是指针。这是一个内置的类型赋值。

一般模式是,如果一个类持有一个资源,那么它的析构函数将释放资源(参见 RAII(。所以,毫无疑问,有类似的东西

Vector::~Vector()
{
    delete[] elem;
}

别处。

在对象生存期的不同点,其他操作可能会释放资源,例如,在这种情况下是复制赋值构造函数。如果这样做,那么资源将被仔细重新分配,或者将其设置为指示没有要释放的状态(例如,通过将其设置为 nullptr (。


关于你的第二个问题。Vector 的复制赋值运算符只是为指针赋值 - 涉及递归。

你说得对,p被分配而没有后续调用delete[];但是,正如你也观察到的,p指向的内存也被elem指向

double* p = new double[a.sz]; // allocate memory
delete[] elem; // delete the old memory
elem = p; // point to the new memory allocated

正如其他人指出的那样,elem在析构函数中删除。

没有复制

构造函数调用,因为没有复制:指针elem只是更改它指向的位置。

您担心的delete将在destructor这种情况中完成。

代码所做的是为数据创建空间,复制数据并释放旧内存。将新内存留待以后处理,RAII

对于旁注:

 elem = p

它不会调用class的复制操作,因为它们是指向 POD 的指针,普通旧数据类型