【问题标题】:Difference in ways of deleting object array删除对象数组的方式不同
【发布时间】:2010-10-10 03:45:27
【问题描述】:

以下删除对象数组有什么不同吗?

第一种方式:

MyClass **obj = new MyClass*[NUM];
for (int i=0; i<NUM; i++) obj[i] = new MyClass(val);
obj[0]->method();
for (int i=0; i<NUM; i++) delete obj[i]; /// Deletion1
delete obj;                              /// Deletion1

第二种方式:

MyClass **obj = new MyClass*[NUM];
for (int i=0; i<NUM; i++) obj[i] = new MyClass(val);
obj[0]->method();
delete[] obj;                            /// Deletion2
obj = 0x0;                               /// Deletion2

这两种方法都可行,并且在调试器中看起来很相似。

【问题讨论】:

  • Why is there a delete[] in C++? 的可能重复项
  • "obj = 0x0; /// 删除 2" cmets 是谎言的一个很好的例子!
  • 正确答案根本不是。如果您必须手动删除某些内容,那您就做错了。
  • 克里斯,我不这么认为。就像你所说的那样,解释对我来说还不够。
  • Johnsyweb,它更像是一个边界标志,一个真正的评论。显然,样本正在调查诸如家庭作业之类的事情。

标签: c++ arrays object


【解决方案1】:

两者都不正确。正确的做法是:

for (int i = 0; i < NUM; i++) delete obj[i];
delete[] obj;

在您展示的第一种方式中,您使用delete 来销毁使用new[] 分配的对象,这会导致未定义的行为(如果您使用new[],则必须使用delete[] 销毁该对象)。

在您展示的第二种方式中,您泄漏了您在第一个 for 循环中创建的所有指针。

如果您使用std::vector 而不是动态分配的数组和某种类型的智能指针,那么在大多数代码中您不必担心这一点。

【讨论】:

    【解决方案2】:

    在您的第一个示例中,您为分配的数组成员指向的每个对象显式调用析构函数。然后您将删除指针数组(实际上应该是delete[],因为您将它分配为一个数组,但实际上对于这个示例来说它可能无关紧要)。

    在您的第二个示例中,您只删除了 指针数组,它不会调用指向对象的析构函数。它不知道的原因是您可能已经在编译器不一定知道的其他变量中复制了这些指针。

    如果你要创建一个对象数组而不是指针,像这样:

    MyClass *obj = new MyClass[NUM];
    

    然后delete[] 运算符将自动为分配的数组中的每个NUM 对象调用析构函数。

    【讨论】:

    • 谢谢格雷格。我不想使用您建议的方式的原因是使用非定义构造函数 new MyClass(val)。我只是对删除疑问感到困惑。
    猜你喜欢
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2014-06-15
    • 2012-04-08
    相关资源
    最近更新 更多