今天,在写A*寻路算法的过程中,遇到了一个段错误,花了好久才搞定,特此记录。
问题描述
涉及到的关键代码主要有两个部分:
1、搜索树结构体的定义中,加入了Vector<TreeNode*> pChildren容器用于储存孩子结点的地址
//A*搜索树结构
struct TreeNode
{
Pos MyPos; //位置信息
TreeNode* pParent = nullptr; //父结点指针
vector<TreeNode*> pChildren; //孩子结点指针
};
2、在主函数的某一循环体中,使用push_back()函数给pChildren容器添加元素
for (int i = 0; i < 8; i++)
{
……
if(……)
{
//创建新结点
pNew = CreateTreeNode(TempPos);
//结点设置为pTempNode的子结点
pTempNode->pChildren.push_back(pNew);
……
}
}
程序运行异常:pTempNode->pChildren.push_back(pNew); 容器每次在添加第6个元素时就会发生段错误,程序中断。
原因分析
先说结论:该段错误是由于当前Vector容器大小已达到容器容量上限,再次给容器添加元素导致内存空间不足,从而触发段错误。
1、当一个Vector容器被定义时,系统会给Vector分配一定的内存空间(Capacity),当Vector中元素不断增加至将要超过该容量时,
系统会分配一个更大的内存空间,在将之前的元素复制到新空间中,在新空间中继续添加元素。
2、结构体的数据成员是储存在一段连续的内存空间中的,且该空间大小通常是无法改变的。
当Vector被定义在结构体中时,遇到容量不足的情况,无法开辟新内存空间以存储新元素,便会导致内存不足,程序中断。
解决办法
我目前只想到了一个比较笨的方法,放弃在结构体中使用Vector,改为定义多个指针。
相关代码修改如下:
//A*搜索树结构
struct TreeNode
{
Pos MyPos; //位置信息
TreeNode* pParent = nullptr; //父结点指针
TreeNode* pChild0 = nullptr; //孩子0结点指针
TreeNode* pChild1 = nullptr; //孩子1结点指针
TreeNode* pChild2 = nullptr; //孩子2结点指针
TreeNode* pChild3 = nullptr; //孩子3结点指针
TreeNode* pChild4 = nullptr; //孩子4结点指针
TreeNode* pChild5 = nullptr; //孩子5结点指针
TreeNode* pChild6 = nullptr; //孩子6结点指针
TreeNode* pChild7 = nullptr; //孩子7结点指针
};
for (int i = 0; i < 8; i++)
{
……
if(……)
{
//创建新结点
pNew = CreateTreeNode(TempPos);
//结点设置为pTempNode的子结点
switch (i)
{
case 0: pTempNode->pChild0 = pNew; break;
case 1: pTempNode->pChild1 = pNew; break;
case 2: pTempNode->pChild2 = pNew; break;
case 3: pTempNode->pChild3 = pNew; break;
case 4: pTempNode->pChild4 = pNew; break;
case 5: pTempNode->pChild5 = pNew; break;
case 6: pTempNode->pChild6 = pNew; break;
case 7: pTempNode->pChild7 = pNew; break;
default: break;
}
}
}
版权声明:本文为weixin_44928892原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。