Как в третьем вызове temp2-> next может получить доступ к адресу второго узла, когда адрес был уничтожен из-за локальной области видимости? - PullRequest
1 голос
/ 01 сентября 2011
struct node {
    char name[20];
    int age;
    int height;
    node* next; // Pointer to the next node
};
node* startPTR = NULL; // global

void addNode_AT_END() {
    node *temp1;
    node *temp2;

    temp1 = new node;  

    cout << "Enter the name : ";
    cin  >> temp1->name;
    cout << endl << "Enter the age : ";
    cin  >> temp1->age;
    cout << endl << "Enter height : ";
    cin  >> temp1->height;

    temp1->next = NULL;

    if( startPTR == NULL) {
       startPTR = temp1; 
    }  else {
       temp2 = startPTR;

       while( temp2->next != NULL )
           temp2 = temp2->next;

       temp2->next = temp1;
    }
 }

В этом фрагменте, когда функция вызывается в третий раз, остальная часть работает.Адрес startPTR присваивается temp2.Теперь, что содержит temp2->next, когда условие проверяется в цикле while?(во время третьего вызова) Если вы говорите, что он содержит адрес второго узла, расскажите, пожалуйста, как он узнает адрес второго узла, потому что мы присвоили адрес второго узла первому узлу во время второго вызоваиспользуя оператор temp2->next = temp1, но из-за его локальной области видимости мы теряем адрес.

Это то, о чем я сейчас думаю. Пожалуйста, объясните, как проверяется условие при третьем вызове функции и каксвязанный список формируется?

Ответы [ 2 ]

4 голосов
/ 01 сентября 2011

Только переменные указателя temp1 и temp2 имеют локальную область видимости.Фактические узлы связанного списка (типа struct node) распределяются в куче посредством вызова new.Данные, выделенные в куче, сохраняются до тех пор, пока они не будут освобождены посредством вызова delete.

. Это означает, что строка temp2->next = temp1 хранит адрес нового узла, который добавляется в конец списка, и этоинформация будет доступна при последующих вызовах функции addNode_AT_END.

Код, похоже, имеет множество проблем - вы используете глобальные переменные, если только нет последующих вызовов к delete где-то в вашей памятиУтечки, уже есть класс контейнера std std::list, который доступен ...

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ: Относительно вашего комментария - когда вы делаете вызов new node, вы создаетеnode объект в куче.Этот объект будет доступен для использования до следующего вызова delete.

Когда вы совершаете вызов temp2->next = temp1, верно следующее:

  1. temp2 указывает наадрес в памяти, где хранится последний узел в списке (этот узел был бы создан путем вызова new на последней итерации).
  2. Присвоено значение переменной-указателя temp1как указатель next для последнего узла в списке (данные «указали» на temp2).Это означает, что адрес хранится в куче , а не в пределах локального указателя temp2.

Когда ваша функция завершает работу, да переменные локального указателя temp1 иtemp2 выходит из области видимости, но выделенные узлы связанного списка heap не уничтожаются - и именно здесь хранятся адреса.

EDIT: Второй комментарий - в else ветвь функции, указатель temp2 инициализируется так, чтобы указывать на начало списка строкой temp2 = startPTR;

Следующие строки (цикл while) пересекают связанный список изголовной узел до тех пор, пока указатель temp2 не укажет на последний узел в списке (до temp2->next = NULL)

На этом этапе новый узел добавляется в список, как обсуждалось выше.

1 голос
/ 01 сентября 2011

Во время третьего вызова temp2->next в первой итерации цикла while указывает на второй узел.Ключом здесь является строка

temp1 = new node;

Когда вы используете оператор new, это выделяет объект в куче (динамическое выделение) и возвращает вам указатель на него.Все, что выделено в куче с помощью new, сохраняется до тех пор, пока вы не используете delete для указателя на эту память.Теперь переменная temp1 сама по себе является просто указателем на стек, который является локальной переменной.Это только означает, что указатель temp1 выйдет из области видимости, но вы уже указали указатель next первого узла на объект второго узла, который был в куче, поэтому он все еще там.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...