像往常一样用“物理a”创建box2d引擎。这在例子中工作正常。但是,如果我们使用myphysics.push_back({});
将新实例添加为std :: vector,则在执行二进制文件后,命令行上会显示以下错误:
“双重免费或腐败(!prev)Aborted(core dumped)”
我完全不知道,消息的含义是什么,或者box2d引擎的向量是什么问题。这是源代码:
// g++ -std=c++14 -lBox2D rrt.cpp
#include <Box2D/Box2D.h>
#include <vector>
class Physics {
public:
b2World world{b2Vec2(0.f, 9.8f)};
};
class RRT {
public:
std::vector<Physics> myphysics;
RRT() {
myphysics.push_back({});
//Physics a;
}
};
int main()
{
RRT myrrt;
}
答案 0 :(得分:1)
问题主要在于b2World
不是可复制的。
我可以使用以下代码块重现双重免费:
{
b2World woo{b2Vec2(0.f, 9.8f)};
b2World poo{woo};
}
可以通过源代码分析识别此问题。
看一下b2World
类,我们可以看到它没有用户定义的复制构造函数,也没有用户定义的复制赋值方法。此外,代码不使用任何机制来阻止编译器定义它们。因此编译器遵循special member functions的规则并自动生成复制构造函数和复制赋值运算符。这些自动生成的方法都不知道如何处理b2World
导致分配的任何动态分配的内存(例如通过其b2BroadPhase
实例的组合)。这些自动生成的方法只需调用组件实例&#39;复制方法,在这种情况下会导致指向已分配内存的任何指针以复制这些地址。然后在销毁时,类b2BroadPhase
类的析构函数为原始实例的已分配内存调用C库free
函数,并为每个副本再次调用。
Bam !! ......免费加倍!
如果您想知道,可以通过以下方法避免此问题:
b2World
复制构造函数或复制赋值运算符的事情。例如,不是使用b2World
个实例的向量,而是将其作为指向b2World
个实例的指针的向量。您可以将Physics
班级的world
成员定义为以下内容:std::unique_ptr<b2World> world{std::make_unique<b2World>(b2Vec2(0.f, 9.8f))};
。如果您不介意重建Box2D,您可能还想添加这些特殊函数的显式删除定义,以帮助避免这些复制操作(只需将行b2World(const b2World& o) = delete; b2World& operator=(const b2World&) = delete;
添加到{{1}的类定义中在其头文件中)。