C++ 结构成员在收到原始地址作为成员函数参数后指向另一个内存位置

C++ Structure member points to another memory location after receiving original address as member function argument

我正在尝试使用我自己的结构节点来实现图形类型的数据结构。该节点将包含一个节点位置(字符串)、节点描述(如提示,字符串)和一对其他节点位置及其对应节点结构的向量。 向量的想法是包含相邻节点和相邻节点的位置(字符串)。 这是结构定义:-

struct node
{
    string location;
    string prompt;
    vector<pair<string,node>> op;
    void insertNode(const node &b);
    void printAll();
};

void node::insertNode(const node &b)
{   
    op.push_back({b.location,b});
}

void node::printAll()
{   
    cout<<"\n"<<location<<": "<<this;
    cout<<"\n"<<prompt;
    for(int i=0;i<op.size();i++)
    {
        cout<<"\n"<<i+1<<". "<<op[i].first<<": "<<&op[i].second;
    }
    cout<<endl;
}

作为测试,我决定做一个图表。下面是 main() 函数。

int main()
{
    vector<node> nodes;
    nodes.resize(5);

    nodes[0].location = "point1";
    nodes[0].prompt = "This is point1"; 
    nodes[1].location = "point2";
    nodes[1].prompt = "This is point2";
    nodes[2].location = "point3";
    nodes[2].prompt = "This is point3";
    nodes[3].location = "point4";
    nodes[3].prompt = "This is point4";
    nodes[4].location = "point5";
    nodes[4].prompt = "This is point5";

    nodes[0].insertNode(nodes[1]);
    nodes[0].insertNode(nodes[2]);
    nodes[1].insertNode(nodes[0]);
    nodes[1].insertNode(nodes[2]);
    nodes[1].insertNode(nodes[3]);
    nodes[2].insertNode(nodes[0]);
    nodes[2].insertNode(nodes[1]);
    nodes[2].insertNode(nodes[4]);
    nodes[3].insertNode(nodes[1]);
    nodes[3].insertNode(nodes[4]);
    nodes[4].insertNode(nodes[2]);
    nodes[4].insertNode(nodes[3]);

    for(int i=0;i<nodes.size();i++) 
        cout<<&nodes[i]<<endl;  

    for(int i=0;i<nodes.size();i++) 
        nodes[i].printAll();    
    return 0;
}

这就是我得到的输出。问题是调用 insertNode() 函数时的结构地址与在 main() 函数中定义时的地址相同。但是当我调用 printAll() 函数时,结构地址发生了变化。我想通过当前节点访问相邻节点。类似于:node[0].op[0].second.printAll();但由于内存地址不同,我收到的是 NULL 内存。

/*
0xfb1630
0xfb1688
0xfb16e0
0xfb1738
0xfb1790

point1: 0xfb1630
This is point1
1. point2: 0xfb1890
2. point3: 0xfb1908

point2: 0xfb1688
This is point2
1. point1: 0xfb5ea0
2. point3: 0xfb5f18
3. point4: 0xfb5f90

point3: 0xfb16e0
This is point3
1. point1: 0xfb6400
2. point2: 0xfb6478
3. point5: 0xfb64f0

point4: 0xfb1738
This is point4
1. point2: 0xfb6760
2. point5: 0xfb67d8

point5: 0xfb1790
This is point5
1. point3: 0x6325b0
2. point4: 0x632628
*/

我不确定我做错了什么。我的假设是函数中传递的内存地址一定有错误,目前是引用传递。但是如果我把pair里面的节点改成节点指针,那么编译器return"wrong 2nd argument"。 这种方法有什么问题?也欢迎对代码进行改进(可能与原始问题有所不同)。

您在 vector 中存储离散的 node 对象,而不是指向对象的指针(地址)。这就是打印 this 指针时得到不同地址的原因。

void node::insertNode(const node &b)
{   
    op.push_back({b.location,b});//<-- here, you make a copy of b and store it in op
}

如果您想使用指针,请相应地声明您的变量:

struct node
{
    string location;
    string prompt;
    vector<pair<string,const node*>> op;//<-- pair of string and pointer to node
    void insertNode(const node &b);
    void printAll();
};

void node::insertNode(const node &b)
{   
    op.push_back({b.location,&b});//<-- insert address of b
}

void node::printAll()
{   
    cout<<"\n"<<location<<": "<<this;
    cout<<"\n"<<prompt;
    for(int i=0;i<op.size();i++)
    {
        cout<<"\n"<<i+1<<". "<<op[i].first<<": "<<op[i].second;//<-- no need for `&` anymore
    }
    cout<<endl;
}

根据评论

编辑添加const