在 C++ 中删除指针数组时析构函数崩溃
Destructor crashing when deleting an array of pointers in C++
我制作了一个名为 cell
的 class。在这个 class 里面有一个 cell
指针数组。 header 看起来像这样:
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 循环,代码才能完美结束,但我知道这也必须删除。
我认为我正确地编写了析构函数,不是吗?
您正在尝试取消引用指针和 delete
具有自动存储持续时间且不再在范围内的变量!你的编译器没有警告过你吗?
因此,您的程序的行为是未定义。
你只曾经配对delete[]
和new[]
以及delete
和new
;尽管您可以将 delete
(甚至 new
1)委托给托管指针 class,例如 std::unique_ptr
.
为什么不重构为 std::vector<cell>
并利用 return 值优化?
1 使用 std::make_unique
.
void cell::creatcells()
{
cell c1,c2,c3,c4,c5,c6,c7,c8;
c[0]=&c1;
c[1]=&c2;
...
以上所有cell
对象都在createcells()
结束时自动销毁。所以delete c[i];
在析构函数中是UB.What你想要的是
c[0]= new cell();
c[1]= new cell();
在 cell::createcells
函数中变量是 local 并且超出范围并且一旦函数 returns 被破坏。当您尝试删除它们时,这些对象将不存在。取消引用这些指针将导致 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.
完全删除构造函数和析构函数
我制作了一个名为 cell
的 class。在这个 class 里面有一个 cell
指针数组。 header 看起来像这样:
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 循环,代码才能完美结束,但我知道这也必须删除。
我认为我正确地编写了析构函数,不是吗?
您正在尝试取消引用指针和 delete
具有自动存储持续时间且不再在范围内的变量!你的编译器没有警告过你吗?
因此,您的程序的行为是未定义。
你只曾经配对delete[]
和new[]
以及delete
和new
;尽管您可以将 delete
(甚至 new
1)委托给托管指针 class,例如 std::unique_ptr
.
为什么不重构为 std::vector<cell>
并利用 return 值优化?
1 使用 std::make_unique
.
void cell::creatcells()
{
cell c1,c2,c3,c4,c5,c6,c7,c8;
c[0]=&c1;
c[1]=&c2;
...
以上所有cell
对象都在createcells()
结束时自动销毁。所以delete c[i];
在析构函数中是UB.What你想要的是
c[0]= new cell();
c[1]= new cell();
在 cell::createcells
函数中变量是 local 并且超出范围并且一旦函数 returns 被破坏。当您尝试删除它们时,这些对象将不存在。取消引用这些指针将导致 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.