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