#c #recursion #memory-management #singly-linked-list
#c #рекурсия #управление памятью #односвязный список
Вопрос:
Я задаю несколько основных вопросов по leetcode. Здесь я пытаюсь поменять местами пары односвязного списка, используя рекурсию. Приведенный ниже код проходит тесты, но какой-то момент ускользает от меня. new_head
является указателем, созданным в стеке. Я понимаю, это означает, что как только функция возвращает результат, она очищается и потенциально может указывать на мусор. Правильно ли предполагать, что здесь это работает «случайно» и не является правильным способом сделать это или мое понимание неверно?
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* swapPairs(struct ListNode* head){
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* new_head;
new_head = head->next;
head->next = swapPairs(head->next->next);
new_head->next = head;
return new_head;
}
Еще один вопрос, связанный с приведенным выше кодом:
если я изменяю порядок назначений, я получаю переполнение стека, но я не могу понять причину, почему
new_head = head->next;
new_head->next = head;
head->next = swapPairs(head->next->next);
Ничто из того, что затронуто в этой строке new_head->next = head;
, не влияет на то, что происходит внутри рекурсии no (ну, должно быть, но я это пропустил)?
Комментарии:
1. Если вы обнаружите, что набираете «Еще один вопрос», пожалуйста, остановитесь и подумайте о создании отдельного вопроса. В противном случае вы рискуете, что ваш вопрос будет помечен как не относящийся к теме из-за отсутствия внимания к одной проблеме.
2. в этом конкретном фрагменте кода есть утечка. new_head = head->next; переменная new_head больше нигде не используется. белый new_head->next перезаписан в new_head->next = head;
3. @milevyo:
new_head
возвращается вызывающему абоненту.
Ответ №1:
Первый вопрос
Return return new_head;
не возвращает объект new_head
вызывающему объекту. Он возвращает вызывающему абоненту текущее значение new_head
. Это прекрасно.
Второй вопрос
С:
new_head = head->next;
head->next = swapPairs(head->next->next);
new_head->next = head;
в момент swapPairs
вызова значение, переданное ему, head->next->next
, является адресом некоторого узла, находящегося за пределами head->next
списка.
С:
new_head = head->next;
new_head->next = head;
head->next = swapPairs(head->next->next);
во время swapPairs
вызова ему передается значение, head->next->next
head
, потому new_head->next = head;
что просто установлено head->next->next
значение head
.
Комментарии:
1. в этом конкретном фрагменте кода есть утечка.
new_head = head->next;
переменнаяnew_head
больше нигде не используется. белыйnew_head->next
был перезаписан вnew_head->next = head;