我最近在我的程序中遇到了一个问题,似乎没有人遇到过这个问题,我已经在互联网上寻找解决方案,但我找不到它,让我解释一下。
我一直在研究2D平台游戏已经有一段时间了,我正在慢慢实现新功能,但是,我遇到了麻烦。我目前正在将AABB树实现编程到我的游戏中用于碰撞和物理目的,这似乎造成了很多麻烦。我最终修复了程序中的所有错误并得到了一个有效的实现,至少,我认为我做了直到随机错误开始出现。令我惊讶的是,它实际上并不是我的AABB类,而是这一段代码。
while (fs.tellg() < Size) {
unsigned short int x, y, w, h;
fs.read(reinterpret_cast<char *>(&x), 2);//I'm reading from a binary
fs.read(reinterpret_cast<char *>(&y), 2);//file containing the AABB
fs.read(reinterpret_cast<char *>(&w), 2);//rectangle points
fs.read(reinterpret_cast<char *>(&h), 2);// x,y, width,height
//These are the two lines where the error occurs
unsigned nodeNum = tree.allocateNode(x*35, y*35, w*35, h*35);
tree.insertLeaf(nodeNum); //Here is where it crashes
};
但是抱着你的马,这不是完整的故事......
当我诊断出这个错误时,我遇到了一些有趣的事情。
1。该程序实际上在一小部分时间内完美运行。我设置
在命令末尾添加system("pause");
以查看它是否会运行
它确实做到了!在我击中后,它也立即崩溃了
暂停。
2。这出于某种原因可以正常使用
unsigned nodeNum = tree.allocateNode();
tree.insertLeaf(nodeNum);
unsigned nodeNum2 = tree.allocateNode();
unsigned nodeNum3 = tree.allocateNode();
tree.insertLeaf(nodeNum3);
tree.insertLeaf(nodeNum2);
但是这根本不起作用,它实际上会使程序崩溃。
unsigned nodeNum = yahh.allocateNode();
tree.insertLeaf(nodeNum);
unsigned nodeNum2 = yahh.allocateNode();
tree.insertLeaf(nodeNum2);
unsigned nodeNum3 = yahh.allocateNode();
tree.insertLeaf(nodeNum3);
这也有效。
unsigned nodeNum2 = tree.allocateNode();
tree.insertLeaf(nodeNum2);
unsigned nodeNum2 = tree.allocateNode();
//tree.insertLeaf(nodeNum2);
但事实并非如此。好像在调用allocateNode();
和。{
insetLeaf();
命令两次命令崩溃程序...
unsigned nodeNum2 = tree.allocateNode();
tree.insertLeaf(nodeNum2);
unsigned nodeNum2 = tree.allocateNode();
tree.insertLeaf(nodeNum2);
AABBtree.h
#define AABB_NULL_NODE 0xffffffff
struct AABBNode {
unsigned nodeNum;
//AABBNode(unsigned _newNode) : _newNode(nodeNum) { };
~AABBNode(){ };
};
//==========================================================================
//==========================================================================
class AABBtree {
private:
unsigned _rootNode = AABB_NULL_NODE;
std::vector<AABBNode> _nodeTable;
public:
AABBtree() { };
~AABBtree(){ };
unsigned allocateNode() {
//Allocate node and return new Node index
unsigned nodeNum = _nodeTable.size();
_nodeTable.emplace_back(nodeNum);
return nodeNum;
};
void insertLeaf(unsigned& nodeNum) {
AABBNode& newNode = _nodeTable[nodeNum];
//Allocate a new AABB, it will be curNode and newNode new parent.
unsigned newParentIndex = allocateNode();
AABBNode& newParent = _nodeTable[newParentIndex];
};
};
Main.cpp的
AABBtree tree;
int main() {
unsigned nodeNum = tree.allocateNode();
tree.insertLeaf(nodeNum);
unsigned nodeNum2 = tree.allocateNode();
tree.insertLeaf(nodeNum2);
};
我已将大部分零件削减到最低限度
答案 0 :(得分:4)
我认为问题与您的insertLeaf
方法有关。
void insertLeaf(unsigned& nodeNum) {
AABBNode& newNode = _nodeTable[nodeNum];
//Allocate a new AABB, it will be curNode and newNode new parent.
unsigned newParentIndex = allocateNode();
AABBNode& newParent = _nodeTable[newParentIndex];
}
此方法首先获取向量(_nodeTable
)内对象的引用。
接下来,它会调用allocateNode()
。在allocateNode
方法中,它会在向量上调用emplace_back
,这可能会增加_nodeTable
的大小。
这就是问题所在 - 如果向量由于达到了容量而必须进行调整大小,那么在调用allocateNode
之前你已经丢失了你的引用。您现在拥有所谓的悬空引用,即未绑定到内存中对象的引用。
如果在调用_nodeTable
之后emplace_back
调整大小,然后返回insertLeaf
方法,则现在您的节点参考无效。
std::vector::capacity
。std::vector::reserve
方法