Член структуры C ++ указывает на другое место в памяти после получения исходного адреса в качестве аргумента функции-члена - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь реализовать структуру данных типа Graph, используя собственный узел структуры. Узел будет содержать местоположение узла (String), описание узла (как приглашение, String) и вектор пары других местоположений узла и соответствующих им структур узлов. Идея вектора состоит в том, чтобы содержать соседний узел и местоположение соседнего узла (String). Вот определение структуры: -

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 (); но поскольку адреса памяти разные, я получаю пустую память.

/*
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
*/

Я не уверен, что делаю неправильно. Я предполагаю, что должна быть ошибка в адресе памяти, передаваемом в функцию, которая в данный момент передается по ссылке. Но если я изменю узел внутри пары на указатель узла, то компилятор вернет «неверный второй аргумент». Что не так с подходом? Также приветствуются улучшения в коде (которые могут отличаться от исходного вопроса).

1 Ответ

0 голосов
/ 15 апреля 2020

Вы храните дискретные node объекты в вашем vector, а не указатели (адреса) на объекты. Вот почему вы получаете разные адреса при печати указателя 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 согласно комментариям

...