Указатель free (temp) освобождает указатель головы в связанном списке. Как сохранить указатель на источник списка - PullRequest
0 голосов
/ 21 марта 2012

У меня есть вопрос, если я хочу удалить узел из связанного списка, и я делаю это: Предположим: заголовок указывает на первый узел.

   deleteFirstNode(struct node * head)
  {
   struct node* temp=head;//this line
   temp->next=head->next->next;
   temp->data=head->next->data;
   free(head);
   head=temp;
  } 

1) это удалит первый узел?

2) Если так, когда я освобождаю голову, не освободится ли временный указатель?потому что и temp, и head указывают на одно и то же место в этой строке (см. комментарий в этой строке в коде).Если оба выше верны, как я сохраню указатель на начало списка.?Большое спасибо.

Ответы [ 5 ]

4 голосов
/ 21 марта 2012

я бы передал двойной указатель и сделал бы что-нибудь в этих строках

deleteFirstNode(struct node ** head) {
  struct node* temp= *head;
  *head = temp->next;
  free(temp);
} 
1 голос
/ 21 марта 2012

Вы хотите удалить узел, на который указывает head;у вас есть несколько проблем:

1) вы передаете копию указателя head - функция не может изменить исходный указатель head, с которым была вызвана функция, поэтому последняя строка функцииhead=temp ничего не делает на самом деле.Когда функция вернет все, что вы указали на первый узел в списке, теперь будет указывать на освобожденную память.По сути, вы потеряли список.

2) когда вы захватываете head->next->data, вы не получаете нужный элемент данных, потому что head->next был перезаписан.

3) free(head) также освободит temp, поскольку оно указывает на то же, что и head.temp бессмысленно.

Некоторые примечания в коде:

deleteFirstNode(struct node * head)
{
    struct node* temp=head;

    temp->next=head->next->next;  // note: this overwrites head->next
    temp->data=head->next->data;  //       so this gets what used to be
                                  //         head->next->next->data

    free(head);     // this frees `temp` (which is an alias for `head`)
                    //      - so whats the point of `temp`?

    head=temp;      // this is pointless in more ways than one
} 

Итак, вот предлагаемая (не проверенная) альтернативная версия deleteFirstNode():

deleteFirstNode(struct node ** head)
{
    struct node* temp = *head;      // temp points to the node we want to free
    struct node* next = temp->next; // next points to what will be the new
                                    //  first node

    free(temp);
    *head=next;
} 

Вам придется вызывать функцию, передав указатель на указатель головы:

struct node* head_pointer;

// ...

deleteFirstNode(&head_pointer);

Еще один момент, который следует учитывать:

  • , если указатель вашей головы равен NULLdeleteFirstNode() не будет работать.Вы должны заставить его справиться с этим делом.
1 голос
/ 21 марта 2012

удалит ли это первый узел?

Да.

Если так, когда я освобождаю голову, не освободится ли временный указатель?потому что как temp, так и head указывают на одно и то же место в этой строке (см. комментарий в «этой строке» в коде).

Да, это освободит память, указанную temp, так же как оба head и temp указывают на одну и ту же память.Указатель head будет указывать на недопустимую область памяти после выполнения этого метода.

1 голос
/ 21 марта 2012

Да, у вас есть два указателя, указывающих на один и тот же адрес.
Так что освобождение памяти путем вызова free() на любом из них освободит указанную память.

EDIT:
Для понимания списков ссылок всегда рисуйте их на листе бумаги.

-------------      ------------       ----------- 
|           |      |          |       |         |
|   head    |----->|  first   |------>| second  | 
|           |      |          |       |         |
-------------      ------------       -----------    

Шаги, которые вам нужно сделать:

Изолят first.
Заставьте head указать на Second.
бесплатно first.

temp = head->next; //temp now points to first
head = temp->next; //head now points to second
free(temp);
0 голосов
/ 21 марта 2012

Из ваших предложений, приведенных выше, мой последний код для удаления первого узла и возврата указателя на головной узел (который будет вторым узлом в списке).

 struct node* freeFirstNode(struct node* head)
{
 struct node* temp;
 temp=head//edited after expert's comment
 temp->next=head->next;//please confirm if this is valid and not Bad pointer.
 temp->data=head->data;
 free(head);//how will I fix this? it will free temp too.
 return(temp);
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...