[英]segmentation fault for deleting a pointer
#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)中,它给出了分段错误。 无法弄清楚,为什么? 任何帮助/指针/建议将不胜感激。
注 - 类是以钻石问题的形式派生的。
这是未定义的行为。 正如您所见,在某些情况下它似乎运作良好,在某些情况下它不会。
至少基类c3
(或c1
和c2
)应该有一个虚析构函数。 例如
class c3 : public c1 {
public:
virtual ~c3() {}
};
根据标准, $ 5.3.5 / 3删除[expr.delete] :
(强调我的)
在第一个备选( 删除对象 )中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类, 静态类型应具有虚拟析构函数或行为未定义 。
试图删除未由new
返回的指针。 对于解决方案,使用基类的virtual destructor
。 通过指向基类的指针删除对象时,基类需要一个virtual
析构函数。
要添加到上一个答案, undefined
行为来自于将指针转换为基类意味着(大部分时间,但不是在您的示例中) 切片 :指针被调整(即递增)以指向开头嵌入式类。
因此,在增加指针上调用delete
时,您可能会释放部分内存并让其中的一部分悬空 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.