Весьма вероятно, что ваша программа вылетает , и это из-за l oop
while (strcmp(curr1->next->name, name)!=0 && curr1 !=NULL)
Здесь есть две ошибки:
-
Порядок, в котором вы делаете сравнения. Логический оператор AND &&
всегда будет сначала вычислять левую часть, что означает, что вы будете разыменовывать указатель curr1
, когда он NULL
. Вам нужно изменить порядок двух сравнений, чтобы сначала проверить curr1 != NULL
.
Вторая проблема заключается в том, что вы не проверяете, является ли curr1->next
нулевым указателем, что означает, что уже на последнем узле в списке вы будете разыменовывать указатель NULL
.
Я предлагаю вам изменить значение l oop на , начинающееся с второй узел в списке, и во время итерации вместо этого проверьте «текущий» узел:
struct data *curr1 = (*head)->next;
while (curr1 != NULL && strcmp(curr1->name, name) != 0)
{
printf("%p\n", (void *) curr1); // Changed to the format specifier %p, to print pointers
curr1 = curr1->next;
}
После этого l oop curr1
будет указателем NULL
, если имя не было нашел. Или указатель на узел, содержащий имя:
if (curr1 == NULL)
{
printf("No Data to Delete\n");
}
else
{
// Node found, remove it
}
Теперь, чтобы помочь вам с самим удалением, для этого вам нужно отследить предыдущий узел, который это можно сделать, изменив l oop как
struct data *curr = (*head)->next;
struct data *prev;
while (curr != NULL && strcmp(curr->name, name) != 0)
{
prev = curr; // Keep track of the previous node
curr = curr->next;
}
Теперь легко отсоединить узел curr
от списка:
prev->next = curr->next;
И, конечно, добавить специальный случай чтобы увидеть, удаляем ли мы хвост:
if (prev->next == NULL)
*tail = prev;
С некоторыми дополнительными изменениями вам не нужно иметь чеки на *head == *tail
или strcmp((*head)->name, name)==0
. Эти случаи можно поместить в более общий случай c с l oop на самом деле.
Собрав все это вместе, ваша функция может выглядеть примерно так:
void popMiddle(struct data **head, struct data **tail, char *name)
{
struct data *curr = *head; // Start iterating at the head
struct data *prev = NULL;
while (curr != NULL && strcmp(curr->name, name) != 0)
{
prev = curr; // Keep track of the previous node
curr = curr->next;
}
if (curr == NULL)
{
printf("No Data to Delete\n");
}
else
{
// Unlink node
if (prev == NULL)
{
// Removed node was the head
*head = curr->next;
if (*head == NULL)
{
// We removed the last node in the list, it's now empty
*tail = NULL;
}
}
else
{
prev->next = curr->next;
if (prev->next == NULL)
*tail = prev; // Removed the tail
}
// Free the found node
free(curr);
}
}