C++:指针的值更改"randomly"

C++: Value of pointer changes "randomly"

本文关键字:randomly 指针 C++      更新时间:2023-10-16

我正在创建一个函数,该函数从带有迷宫的图像创建地图。 它获取图像,转到每个像素并决定是否必须在那里创建一个节点。一条规则是,当它在其中一个边框处找到一个白色像素时,它将是开始或结束节点。为了告诉我的路径查找函数从哪里开始,我将节点推送到向量中(也像所有其他节点一样(,并将该节点的地址保存在(双(指针中。我的问题是,在循环结束时,此节点中的变量会更改其值(布尔变量可能会获得值 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变得"无法访问",当我尝试将某些东西连接到它时,这会导致 sigsegvs。

我的职能:

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;
}

你的主要问题在这里:

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);
}

局部变量不会放在全局堆中,并且在创建它们的代码块完成后不久,程序可能会忘记它。 改进代码的更好方法是将函数声明重写为

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());