gpt4 book ai didi

c++ - 堆栈帧中重复的内联构造函数导致 "pure virtual method called"?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:45:15 25 4
gpt4 key购买 nike

我想知道是否有任何 C++ 专家可以阐明这种奇怪的情况。 Box2D 物理引擎附带的示例之一是崩溃并显示消息“调用纯虚拟方法”,但仅适用于特定编译器(并且仅在发布版本中)。

您可能知道 Box2D 是一段非常可靠的代码,所以我认为这可能是编译器的问题,特别是考虑到它只发生在这个特定的编译器上。我在 Windows7 上使用 mingw32:

> gcc.exe --version
gcc version 4.4.0 (GCC)

以下是 Box2D 相关部分的精简摘录。您可以在以下位置查看完整的源代码:

b2Shape.h
b2CircleShape.h
b2CircleShape.cpp
SensorTest.h

//base class
class b2Shape
{
public:
virtual ~b2Shape() {}
virtual b2Shape* Clone(b2BlockAllocator* allocator) const = 0;
};


//sub class
class b2CircleShape : public b2Shape
{
public:
b2CircleShape();
b2Shape* Clone(b2BlockAllocator* allocator) const;
};

inline b2CircleShape::b2CircleShape() {}

b2Shape* b2CircleShape::Clone(b2BlockAllocator* allocator) const
{
void* mem = allocator->Allocate(sizeof(b2CircleShape));
b2CircleShape* clone = new (mem) b2CircleShape;
*clone = *this;
return clone;
}

注意克隆函数中新的位置。

现在导致问题的执行归结为:

{
b2CircleShape shape;
shape.Clone(allocator); //ok
}
{
b2CircleShape shape;
shape.Clone(allocator); //"pure virtual method called"
}

首先了解了如何调用虚方法之后,我试图弄清楚为什么会发生在这里,因为它不符合在基类构造函数中调用虚函数的经典情况.经过长时间的盲目摸索之后,我想出了上面的最小案例。

我的大胆猜测是编译器足够聪明,可以看到这两个 b2CircleShape 实例没有在同一范围内使用,因此它只为其中一个分配空间并重新使用它。在第一个实例被销毁后,vtable 如预期的那样被清理。然后由于某种原因在构造第二个实例时,vtable没有再次构造......?

我想出了两件事来避免这个问题,但就像我说的那样,它似乎更像是一个编译器问题,所以我并不是说需要更改这段代码。

可疑修复编号 1 是注释掉基类中的虚拟析构函数定义。我读过的关于这个主题的所有信息都表明这不是答案。 (有趣的是,我发现仅仅从基类析构函数中删除 'virtual' 修饰符是不够的。我的理解是编译器会提供一个默认的析构函数 ~b2Shape() {} 如果没有指定,那么为什么结果不同如果我真的指定默认值是什么?好吧,这真的离题了......)

我发现的第 2 个不太可疑的修复是从子类构造函数中删除“内联”。也许在同一个堆栈框架中放置新的内联构造和重用实例不能很好地协同工作。 (更新:进一步检查显示新的展示位置无关紧要)

一些更多的研究告诉我编译器可以自由地做任何关于“内联”建议的事情,所以也许其他编译器没有这个问题,因为他们忽略了“内联”?

最佳答案

这是显而易见的。

A) 如果它按预期工作一次,那么很好。B) 错误再次发生的事实只能说明它是您的 gcc 中的错误。是的,这些东西确实会有错误。我在除 MSVC 编译器之外的所有编译器中都看到了错误。

如果您获得 GCC 或 Clang 或其他任何代码并找到错误发生的位置,那么那里的错误将是由于它读取的一些标志。如果它工作一次然后再次失败,那么编译器数据中的标志或位已更改,这意味着内存溢出或编译器中的其他拼写错误。

对不起。

关于c++ - 堆栈帧中重复的内联构造函数导致 "pure virtual method called"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12122706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com