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

时间:2018-01-15 23:53:07

标签: c++ windows codeblocks

我最近在我的程序中遇到了一个问题,似乎没有人遇到过这个问题,我已经在互联网上寻找解决方案,但我找不到它,让我解释一下。

问题

我一直在研究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);
};

我已将大部分零件削减到最低限度

1 个答案:

答案 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方法,则现在您的节点参考无效。

快速修复