我正在创建一个函数,可以从包含迷宫的图像创建地图。 它获取图像,转到每个像素并决定是否必须在那里创建一个节点。一个规则是,当它在其中一个边界处找到白色像素时,它将是开始节点或结束节点。为了告诉我的寻路函数从哪里开始,我将节点推入一个向量(就像所有其他节点一样)并将该节点的地址保存在(双)指针中。我的问题是,在循环结束时,此节点中的变量会更改它们的值(bool变量可能会得到值133)我实际上从不修改此循环中的大多数成员。我真的不知道为什么会这样......
例如:
将节点分配给指针后:
Completed: false
DistanceTo: 4294967295
PreviousNode: 0x0
XPos: 3
YPos: 0
m_vConnections: <0 Elements>
功能完成后:
Completed: 8
DistanceTo: 32674
PreviousNode: SomeAddress
XPos: 3
YPos: 0
m_vConnections: <0 Elements>
SomeAddress上的节点实际上也完全搞砸了值,但是我怀疑地址刚改变了,它现在将那里的数据解释为一个节点。 有时m_vConnections变得“无法访问”,当我尝试连接到它时,会导致sigsegv。
我的功能:
bool CreateGraph(const sf::Image &mMaze, std::vector<dijkstra::CNode> *vGraph, dijkstra::CNode **mStart, dijkstra::CNode **mEnd, SMazeCol mColors)
{
*mStart = 0;
unsigned short nExits = 0;
//Get Maze Colours
sf::Color mWallColor = mColors.Wall;
sf::Color mPathColor = mColors.Path;
//Create nodes
for(unsigned int y = 0; y < mMaze.getSize().y; ++y)
{
for(unsigned int x = 0; x < mMaze.getSize().x; ++x)
{
if(mMaze.getPixel(x, y) == mPathColor) //Current pixel is a path
{
bool bTop = false;
bool bBottom = false;
unsigned short nNeighbours = 0;
//Check surroundings of pixel
if(y != 0 && mMaze.getPixel(x, y - 1) == mPathColor)
{
bTop = true;
++nNeighbours;
}
if(y != mMaze.getSize().y - 1 && mMaze.getPixel(x, y + 1) == mPathColor)
{
bBottom = true;
++nNeighbours;
}
if(x != 0 && mMaze.getPixel(x - 1, y) == mPathColor)
{
++nNeighbours;
}
if(x != mMaze.getSize().x - 1 && mMaze.getPixel(x + 1, y) == mPathColor)
{
++nNeighbours;
}
//Decide if a node has to be created at that pixel
if(x == 0 || y == 0 || x == mMaze.getSize().x - 1 || y == mMaze.getSize().y - 1)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
if(*mStart == 0)
{
*mStart = &vGraph->back();
++nExits;
}
else
{
*mEnd = &vGraph->back();
++nExits;
}
}
else if(nNeighbours == 2 && bTop != bBottom)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
}
else if(nNeighbours > 2)
{
dijkstra::CNode mNode;
mNode.XPos = x;
mNode.YPos = y;
vGraph->push_back(mNode);
}
}
}
}
if(nExits != 2)
return false;
CNode类:
struct SConnection
{
SConnection(CNode *To, unsigned int Distance);
CNode *To;
unsigned int Distance;
};
class CNode
{
public:
CNode();
std::vector<SConnection> Connections()const;
bool AddConnection(CNode *mTo, unsigned int nDistance);
bool AddConnection(const SConnection &mConnection);
bool RemoveConnection(CNode *mTo);
bool operator > (const CNode &rhs)const;
bool operator < (const CNode &rhs)const;
bool operator == (const CNode &rhs)const;
CNode* Addr();
bool Completed;
unsigned int DistanceTo;
CNode *PreviousNode;
unsigned int XPos, YPos;
private:
std::vector<SConnection> m_vConnections;
};
实现:
SConnection::SConnection(CNode *To, unsigned int Distance)
{
this->Distance = Distance;
this->To = To;
}
CNode::CNode()
:Completed(false), DistanceTo(std::numeric_limits<unsigned int>::max()), PreviousNode(0)
{
}
std::vector<SConnection> CNode::Connections() const
{
return m_vConnections;
}
bool CNode::AddConnection(CNode *mTo, unsigned int nDistance)
{
if(mTo == 0)
return false;
if(mTo == this)
return false;
for(auto &it : m_vConnections)
{
if(it.To == mTo)
return false;
}
m_vConnections.push_back({mTo, nDistance});
mTo->m_vConnections.push_back({this, nDistance});
return true;
}
bool CNode::AddConnection(const SConnection &mConnection)
{
return (AddConnection(mConnection.To, mConnection.Distance));
}
bool CNode::RemoveConnection(CNode *mTo)
{
for(auto it = m_vConnections.begin(); it != m_vConnections.end(); ++it)
{
if(it->To == mTo)
{
m_vConnections.erase(it);
for(auto it2 = mTo->m_vConnections.begin(); it2 != m_vConnections.end(); ++it2)
{
if(it2->To == this)
mTo->m_vConnections.erase(it2);
}
}
}
return false;
}
bool CNode::operator >(const CNode &rhs)const
{
return DistanceTo > rhs.DistanceTo;
}
bool CNode::operator <(const CNode &rhs) const
{
return DistanceTo < rhs.DistanceTo;
}
bool CNode::operator ==(const CNode &rhs)const
{
return DistanceTo == rhs.DistanceTo;
}
CNode *CNode::Addr()
{
return this;
}
答案 0 :(得分:0)
你的主要问题在于:
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
if(*mStart == 0)
{
*mStart = &vGraph->back();
++nExits;
}
else
{
*mEnd = &vGraph->back();
++nExits;
}
}
else if(nNeighbours == 2 && bTop != bBottom)
{
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
}
else if(nNeighbours > 2)
{
dijkstra::CNode mNode;
//...
vGraph->push_back(mNode);
}
本地变量不会放在全局堆中,并且在创建它们的代码块完成后很快就会被programm忘记。 改进代码的更好方法是将函数声明重写为
bool CreateGraph(const sf::Image &mMaze, std::vector<dijkstra::CNode*> *vGraph, dijkstra::CNode **mStart, dijkstra::CNode **mEnd, SMazeCol mColors)
内部功能全部改变:
dijkstra::CNode mNode
vGraph->push_back(mNode);
到
std::shared_ptr<dijkstra::CNode> mNode =
std::shared_ptr<dijkstra::CNode>(new dijkstra::CNode(X, Y));
vGraph->push_back(mNode.get());