#include <iostream>
using namespace std;
class c1 {};
class c2 : public c1 {};
class c3 : public c1 {};
class c4 : public c2, public c3 {};
int main () {
c4 *x1 = new c4;
c3 *x2 = x1;
delete x2; // segmentation fault
}
嗨,我想了解类型转换和继承,我发现了这个问题。我有一个指向最派生类的指针,并且对任何类中间进行了类型化(隐式),而删除时,我认为它应该能够通过第一个新删除已分配的空间。在一些编译器中,它似乎很好,但在linux gcc版本4.7.2(Debian 4.7.2-5)中,它给出了分段错误。无法弄清楚,为什么?任何帮助/指针/建议将不胜感激。
注意 - 类是以钻石问题的形式派生的。
答案 0 :(得分:3)
这是未定义的行为。就像你看到的那样,在某些情况下它似乎运作良好,在某些情况下它不会。
至少基类c3
(或c1
和c2
)应该有虚拟析构函数。 e.g。
class c3 : public c1 {
public:
virtual ~c3() {}
};
根据标准,$5.3.5/3 Delete [expr.delete]:
(强调我的)
在第一个备选方案(删除对象)中,如果是静态类型的话 要删除的对象不同于其动态类型,静态 type应该是对象的动态类型的基类 删除和静态类型应具有虚拟析构函数或 行为未定义。
答案 1 :(得分:2)
尝试删除this.setState({data: res.data.result_set});
未返回的指针。对于解决方案,使用_createMenuItems(){
return this.state.data.map((loaddata, index)=>
<li key={index}><Link to={/*put the link here*/} >{loaddata.menu_custom_title}</Link></li>
);
}
render() {
return (
<div>
<ul>
<li><Link to="/home" >{this.state.home}</Link></li>
<li><Link to="/about" >{this.state.about}</Link></li>
<li><Link to="/contact" >{this.state.contact}</Link></li>
{this._createMenuItems()}
</ul>
{this.props.children}
</div>
)
}
作为基类。通过指向基类的指针删除对象时,基类需要new
析构函数。
答案 2 :(得分:1)
要添加到上一个答案,undefined
行为来自于将指针强制转换为基类意味着(大部分时间,但不是在您的示例中)切片 :指针被调整(即递增)以指向嵌入类的开头。
因此,在递增指针上调用delete
时,您可能会释放部分内存,并让其中一部分悬空。