用于删除指针的分段错误

时间:2017-01-23 06:28:58

标签: c++ pointers segmentation-fault language-lawyer delete-operator

#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)中,它给出了分段错误。无法弄清楚,为什么?任何帮助/指针/建议将不胜感激。

注意 - 类是以钻石问题的形式派生的。

3 个答案:

答案 0 :(得分:3)

这是未定义的行为。就像你看到的那样,在某些情况下它似乎运作良好,在某些情况下它不会。

至少基类c3(或c1c2)应该有虚拟析构函数。 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时,您可能会释放部分内存,并让其中一部分悬空