C ++:指针的值“随机”变化

时间:2017-08-03 11:33:08

标签: c++ pointers

我正在创建一个函数,可以从包含迷宫的图像创建地图。 它获取图像,转到每个像素并决定是否必须在那里创建一个节点。一个规则是,当它在其中一个边界处找到白色像素时,它将是开始节点或结束节点。为了告诉我的寻路函数从哪里开始,我将节点推入一个向量(就像所有其他节点一样)并将该节点的地址保存在(双)指针中。我的问题是,在循环结束时,此节点中的变量会更改它们的值(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;
}

1 个答案:

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