C++ 指针和数据位置:数据总是被放置在相同的内存位置

Posted

技术标签:

【中文标题】C++ 指针和数据位置:数据总是被放置在相同的内存位置【英文标题】:C++ Pointers and Data Locations: Data Always Being Placed at Same Memory Location 【发布时间】:2015-09-22 18:23:12 【问题描述】:

我正在尝试在 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 的节点总是被放置在同一个数据位置,因此每个 Next 的引用位置总是相同的。如何防止它总是出现在同一个位置?这意味着子节点没有链接到它们的父节点,而是链接到它们自己。我已经用星号标记了错误的来源。

 //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++;

【问题讨论】:

0xfffffffd2b0 通常表示堆栈位置 【参考方案1】:
struct Node initial = orig_config, 0, 0, NULL;

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

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

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

附带说明,struct 关键字在 C++ 中的变量声明中不是必需的。请参阅Why does C need “struct” keyword and not C++? 了解更多信息。

【讨论】:

这听起来很符合正在发生的事情。这就是我对 gdb 的看法,但我不知道如何解决它。那么,我基本上需要在循环的每次迭代中创建一个新节点?那么他们会保留数据吗?我真的很感谢你的帮助,你能说得更详细一点吗?我已经研究这个错误好几个小时了。 是的,使用new 创建的Node 将被放置在堆上并一直保留在内存中,直到程序结束或被删除。 指针的引用仍然总是和内存在同一个地方。在我创建节点的所有位置中,我将其更改为新节点。 @user2055216 你能把你更新的代码发布到coliru 这样我可以看到吗? 我最终弄明白了,是指针语法的东西让我失望了。我很高兴我能够让它编译和工作。顺便说一句,非常感谢你。但是现在,我的迭代深化 DFS 并没有返回最佳解决方案! IDDFS 应该是最优的。就这样。

以上是关于C++ 指针和数据位置:数据总是被放置在相同的内存位置的主要内容,如果未能解决你的问题,请参考以下文章

C++原生指针,引用与智能指针

在特定内存地址创建新的 C++ 对象?

指针总是显示相同的值 C++

C++ 高级数据类型—— 指针

C++ 高级数据类型—— 指针

C++指针的算术运算 关系运算