在C ++中删除指针数组时析构函数崩溃

时间:2017-07-27 12:46:46

标签: c++ crash destructor delete-operator

我创建了一个名为cell的类。在这个类中有一个cell指针数组。标题如下所示:

class cell
{       
 public:
  cell();
  cell *c[8];
  void creatcells();
  virtual ~cell();
  ..

}

并且cpp文件如下所示:

cell::cell()
{
//ctor
 for(int i=0;i<8;i++)
 {
   c[i]=NULL;
 }

}


void cell::creatcells()

 {
   cell c1,c2,c3,c4,c5,c6,c7,c8;

   c[0]=&c1;
   c[1]=&c2;
   c[2]=&c3;
   c[3]=&c4;
   c[4]=&c5;
   c[5]=&c6;
   c[6]=&c7;
   c[7]=&c8;
 }

cell::~cell()
{
    for(int i=0; i<8; i++)
    {
        if (c[i]!=NULL)
        {
                    delete c[i];
        }
    }
    delete[] c;

 }

但每次程序结束时,都会崩溃,为什么? 我试过没有if (c[i]!=NULL),但这没有帮助。只有没有for循环,代码才能完美结束,但我知道这也必须删除。 我想我正确地写了析构函数,不是吗?

3 个答案:

答案 0 :(得分:5)

void cell::creatcells()
 {
   cell c1,c2,c3,c4,c5,c6,c7,c8;

   c[0]=&c1;
   c[1]=&c2;
   ...

所有上述cell个对象都会在createcells()结束时自动销毁。所以析构函数中的delete c[i];是UB。你想要的是

 c[0]= new cell();
 c[1]= new cell();

答案 1 :(得分:4)

您尝试取消引用指向具有自动存储持续时间且不再在范围内的delete变量的指针!你的编译器没有警告过你这个吗?

因此,程序的行为未定义

您只有永远delete[]new[]deletenew配对;虽然您可以将delete(甚至是new 1 )委托给托管指针类,例如std::unique_ptr

为什么不重构std::vector<cell>并使用返回值优化

1 使用std::make_unique

答案 2 :(得分:3)

cell::createcells函数中,变量是 local 并超出范围,并在函数返回后被破坏。当您尝试删除它们时,这些对象不会存在。取消引用这些指针将导致undefined behavior

更不用说您只应delete new。而且,由于您不会new在指针上再次执行delete 导致undefined behavior

简单的解决方案是使用vector对象

std::vector<cell> c;

然后只需向向量添加八个cell个对象:

void cell::creatcells()
{
    c = std::vector<cell>(8);
}

现在,向量将包含八个默认构造的cell对象。无需在构造函数或析构函数中执行任何操作。事实上,我建议你完全按照the rule of zero删除构造函数和析构函数。