【问题标题】:C++: How to properly delete array of pointers to pointers in class destructorC++:如何在类析构函数中正确删除指向指针的指针数组
【发布时间】:2018-09-12 01:23:58
【问题描述】:

我无法理解如何在下面程序的第二类中编写析构函数:

class First
{
    // Assume this is a virtual class
};

class Second
{
    private:
        int index;
        First **arr;

    public:
        Second(int size)
        {
            index = 0;
            arr = new First*[size]; // Please bear with my use of new
        }

        ~Second() {}

        void add(First *f)
        {
            arr[index++] = f;
        }
};

在我发现的所有类似问题中,数组的每个元素都被动态分配一个值,使用 new 如下:arr[i] = new First();。然而,这里的元素被分配了指向作为函数参数的对象的指针的值。那么,析构函数是应该将每个元素一个一个地删除,然后再删除数组,还是足够删除数组呢?

~Second()
{
    for(int i = 0; i < index; ++i) delete[] arr[i]; // Is this necessary?
    delete[] arr;
}

【问题讨论】:

  • arrnew[]-ed,所以应该是 detele[]-ed。是arr[i]new[]-ed 吗?
  • First **arr 替换为std::vector&lt;First*&gt;,或者,如果Second 拥有Firsts,则替换为std::vector&lt;std::unique_ptr&lt;First&gt;&gt;
  • 这取决于指针f 是如何创建的,newnew[]malloc&amp;variable?还有关于调用add 的代码是否会保留所有权并稍后删除对象。 “把自己画到角落里”是我想到的一句话。
  • @DimK - 它必须是对 deletedelete[]freenothing 的匹配调用。但是如果你不知道调用者做了什么,你就不能写它。 :-)
  • 不,我不知道没有其他人。您说过您不确定该指针是如何分配的。为什么你不确定你是不是做这件事的人?如果您正在编写整个程序,您需要确定哪些指针是拥有它们指向的对象,哪些不是。在任何给定的时刻,每个对象都必须有一个拥有指针(尽管不同的指针可能在不同的时刻拥有它,但最好避免这种情况)。 分配该角色。 arr 拥有指针数组。什么拥有数组元素指向的对象?

标签: c++ arrays class pointers destructor


【解决方案1】:

你最好先在构造函数中分配后在数组中保留NULL。

    int arr_size; // you need to define this for the reference in destructor

    Second(int size)
    {
        arr_size = size;
        arr = new First*[size]; // Please bear with my use of new
        for (int i = 0; i < size; i++)
            arr[i] = NULL;
    }

然后,在析构函数中,仅当元素不为 NULL 时才删除该元素,如下所示。

    ~Second()
    {
        for(int i = 0; i < arr_size; i++)
            if (arr[i]) 
                delete arr[i];
        delete[] arr;
    }

【讨论】:

  • 有没有错过index,以及它是如何使用的?
  • @Deduplicator,不,我保留了 index 的用法,用于 add() 来计算数组中元素的实际数量。
【解决方案2】:

在我发现的所有类似问题中,数组的每个元素都被动态分配一个值,使用 new 如下:arr[i] = new First();。然而,这里的元素被分配了指向作为函数参数的对象的指针的值。那么,析构函数是应该把每一个元素一个一个删除再删除数组,还是删除数组就够了呢?

那个,我们无法回答。 Second 是否拥有传递给 .add() 的对象的所有权,如果是,它们是如何分配的?

  1. 如果它没有所有权,只需删除数组就足够了,并且该数组应该由 std::unique_ptr 为您管理。

  2. 如果它确实拥有所有权,.add() 的参数应该是具有正确所有权语义和删除器的智能指针。然后,您的数组应该是这些智能指针的数组,由 std::unique_ptr 管理。

在任何一种情况下,如果您正确使用智能指针,default-dtor 就可以了。

【讨论】:

  • 明白。感谢回复。使用智能指针是处理这个问题的唯一正确方法吗?
猜你喜欢
  • 2010-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-27
  • 1970-01-01
  • 2020-07-10
  • 2019-06-20
  • 2014-12-30
相关资源
最近更新 更多