我有一个类型,作为成员指向另一个对象的指针.创建对象(Demo)时,它会初始化构造函数中的另一个对象(Property).我想如果我有很多这些对象,当我将属性更改为不同的东西时,我不想浪费堆空间,所以我释放了初始化的内存setProperty,然后在Demo的deconstrucor中我再次删除它,因为它会有在那一点上被设定为不同的东西.但是,这会导致代码崩溃.如果我在property重置时重新分配,为什么会崩溃?
class Property{ };
class Demo{
protected:
Property *property;
public:
Demo(){ property = new Property();};
void setProperty(Property *p){
delete property;
property = p;
};
~Demo(){
delete property;
};
};
int main(){
Property p = Property();
Demo * d = new Demo();
d->setProperty(&p);
delete d;
}
Run Code Online (Sandbox Code Playgroud)
您传递未创建的对象的地址,new然后尝试delete它.这是未定义的行为.
最可能的速成课程解释是标准库也可以释放Property p.你首先释放它,然后在程序结束时它再次释放p.
可能的"修复"是传递允许删除的对象,即由其创建new.
int main(){
Property *p = new Property();
Demo * d = new Demo();
d->setProperty(p); // Demo is responsible for freeing `p`.
delete d;
} // standard libraries do clean up objects from `main` here
Run Code Online (Sandbox Code Playgroud)
请注意,有更好,更清晰的方法来实现您要做的事情.这个答案只是解释了崩溃.
你应该看到这一点,这个设计很难选择你是否应该自由.所以你的代码取决于参数来源.这应该是设计的红旗.