C ++指针和数据位置:数据始终放在相同的内存位置

时间:2015-09-22 18:23:13

标签: c++ pointers memory-management

我试图在C ++中实现迭代深化深度优先搜索算法。搜索成功找到问题的解决方案,但是我无法将子节点链接回根节点。

struct Node
{
    std::vector<int> config;
    int depth;
    int action; //0 up 1 down 2 left 3 right
    Node * parent;
    bool operator<(const Node& rhs) const
    {
        return depth < rhs.depth;
    }
};

正如您在我的结构中所看到的,我有一个指向父节点的指针。但是,在我的DFS代码中,我遇到了在循环的每次迭代中更新节点的父指针时遇到的问题。所有节点的父指针始终指向相同的数据位置0xfffffffd2b0。换句话说,始终在此处创建名为Next的新节点。

我相信我的代码中名为Next的Node总是位于同一个数据位置,因此每个Next的引用位置始终相同。如何防止它始终出现在同一位置?这意味着Child节点没有链接到它们的父节点,而是链接到它们自己。我用星号标记了bug的来源。

 //IDDFS Logic:
int Current_Max_Depth = 0;
while(Current_Max_Depth < 20) 
{
    struct Node initial = {orig_config, 0, 0, NULL}; //config, depth, action, parent.
    visited.clear();
    priority_queue<Node> frontier;
    frontier.push(initial);
    while(frontier.size()>0)
    {
        struct Node Next = frontier.top();
        visited.push_back(Next.config);
        frontier.pop();
        if(Next.depth < Current_Max_Depth)
        {
            int pos_of_hole = Find_Position_of_Hole(Next.config);
            if(pos_of_hole==0) 
            {
                 std::vector<int> Down_Child = Move_Down(Next.config);
                 struct Node Down_Node = {Down_Child,Next.depth+1,1,&Next};  //****
                 if(!(std::find(visited.begin(), visited.end(), Down_Child)!=visited.end()))
                 {
                      if(Goal_Test(Down_Child))
                      {
                           goal_node = Down_Node;
                           goal_reached = true;
                           break;
                      }
                 frontier.push(Down_Node);
                 }

                std::vector<int> Right_Child = Move_Right(Next.config);
                struct Node Right_Node = {Right_Child,Next.depth+1,3,&Next}; //*******Passing next by reference here is not working since Next is always at the same data location.  The nodes one layer up from the leaf nodes end up all pointing to themselves.
                if(!(std::find(visited.begin(), visited.end(), Right_Child)!=visited.end()))
                {
                    if(Goal_Test(Right_Child))
                    {
                        goal_node = Right_Node;
                        goal_reached = true;
                        break;
                    }
                 frontier.push(Right_Node);
                 }      
         }
    if(pos_of_hole==1)
    ... does very similar for pos 1 through 8, not related to bug ...
        } //End of if(Next.Depth < Max_Depth)
} //End of while(frontier.size()>0)
if(goal_reached)
{
    break;
} 
Current_Max_Depth++;
}

1 个答案:

答案 0 :(得分:3)

struct Node initial = {orig_config, 0, 0, NULL};

在堆栈上创建Node。当你创建下一个孩子时

struct Node Down_Node = {Down_Child,Next.depth+1,1,&Next};

您正在获取该本地堆栈对象的地址。当循环结束时Next被破坏,然后在while循环的下一次迭代开始时再次构造它。如果节点需要保留,那么您需要使用new然后delete分配它们,然后完成。

另外,C ++中的变量声明不需要struct关键字。有关详细信息,请参阅Why does C need “struct” keyword and not C++?