C++程序中的异常行为,经常崩溃

C++程序中的异常行为,经常崩溃,c++,windows,codeblocks,C++,Windows,Codeblocks,我最近在我的程序中遇到了一个问题,似乎也没有人遇到过这个问题,我在互联网上搜索了一个解决方案,但我就是找不到,让我解释一下 问题 我已经在一个2D平台游戏上工作了一段时间,现在正在慢慢地实现新功能,但是,我遇到了一个障碍。我目前正在为碰撞和物理目的在我的游戏中编程一个AABB树实现,它似乎造成了很多麻烦。我最终修复了程序中的所有错误,并得到了一个有效的实现,至少,我认为我做到了,直到随机错误开始出现。令我惊讶的是,它实际上根本不是我的AABB类,而是这一段代码 while (fs.tellg()

我最近在我的程序中遇到了一个问题,似乎也没有人遇到过这个问题,我在互联网上搜索了一个解决方案,但我就是找不到,让我解释一下

问题 我已经在一个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                                   

};
但这根本不起作用,它实际上使程序崩溃

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;和 内插;命令两次以使程序崩溃

unsigned nodeNum2 = tree.allocateNode();
tree.insertLeaf(nodeNum2);

unsigned nodeNum2 = tree.allocateNode();
tree.insertLeaf(nodeNum2);
源代码 AABBtree.h


我已经将大部分零件切割到了最小值

我相信问题与你的insertLeaf方法有关

此方法首先获取向量节点表中对象的引用

接下来,它调用allocateNode。在allocateNode方法中,它调用向量,这可能会增加_节点表的大小

问题就在这里——如果向量在达到其容量后必须进行调整大小,那么就失去了调用allocateNode之前的引用。您现在拥有了所谓的悬挂引用,即未绑定到内存中对象的引用

如果_nodeTable在调用emplace _back之后调整大小,那么回到insertLeaf方法中,您现在有一个无效的节点引用

快速修复 在获取该引用之前,强制向量保留足够的内存。除此之外,您还可以使用该方法。
这个程序实际上在很小的一部分时间内运行得非常完美——胡乱猜测——你的代码中有一些UB。附加说明:熟悉一个概念。请尽量缩短您的代码,以满足最小部分的要求。您还应包括您遇到的错误。说它崩溃不会给你带来太多帮助。你试过使用调试器吗?我认为问题出在你的insertLeaf方法上。我不是100%确定,但我认为这与悬挂引用有关,这是我的理由:请注意,当向量达到某个阈值时,它可以调整自身大小。执行此操作时,对向量内对象的任何引用都将无效,因此对于AABBNode&newNode=_nodeTable[nodeNum];,在未签名的newParentIndex=allocateNode之后,此newNode可能会变得无效;被称为。删除变量旁边的&并进行复制,查看错误是否仍然存在there@smac89你应该把它变成一个答案。
unsigned nodeNum2 = tree.allocateNode();
tree.insertLeaf(nodeNum2);

unsigned nodeNum2 = tree.allocateNode();
tree.insertLeaf(nodeNum2);
#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];
    };
};
AABBtree tree;
int main() {
    unsigned nodeNum = tree.allocateNode();
    tree.insertLeaf(nodeNum);
    unsigned nodeNum2 = tree.allocateNode();
    tree.insertLeaf(nodeNum2);
};
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];
}