Удаление структуры из двусвязного списка на основе его содержимого (в C) - PullRequest
0 голосов
/ 07 сентября 2018

Моя программа - это базовый интерфейс C, который позволяет пользователю вводить, печатать вперед, печатать назад и удалять записи MP3 из списка. Список реализован в виде двусвязного списка структур MP3 на языке Си.

Все мои функции, кроме Delete, работают нормально. Удалить принимает указатель на головной узел списка и строку символов, указывающую, какие записи исполнителя вы хотите удалить. В моем основном я записываю пользовательский ввод и проверяю, что он записывается правильно. Затем я передаю пользовательский ввод и ссылку на головку в следующую функцию, чтобы удалить указанные записи MP3. Тем не менее, моя программа прекрасно работает и выполняется, но фактически не удаляет записи при вызове функции удаления. Любая помощь приветствуется.

Для ясности я рассмотрел несколько вопросов в стеке относительно удаления узлов из DLL, однако все они касаются простой DLL, содержащей целочисленные значения, и, похоже, не очень хорошо соответствуют моему сценарию. Я прошу прощения, если это будет повторяться вопрос, если так, пожалуйста, укажите мне на вопрос, который я дублирую. Еще раз спасибо за любую помощь. Ниже моя функция

void deleteMP3(struct MP3* head_ref, char* artist)
{
    //Declaring a temp struct to hold the node that needs to be deleted
    struct MP3* temp;

    //Check if the head node contains the artist to be deleted
    if(head_ref->artist == artist)
    {
        //Set temp to the current head ref so it can be deleted
        temp = head_ref;

        //Set head_ref to the next node in the list
        head_ref = head_ref->next;

        //Free the memory associated with the MP3 to be deleted
        free(temp->artist);
        free(temp->title);
        free(temp->date);
        free(temp);
    }

    //Traverse the list checking each MP3's artist field
    while(head_ref != NULL)
    {
        //Check the artist of the current MP3 against the input. Delete it if it needs to be deleted
        if(head_ref->artist == artist)
        {
            //Set temp to the current MP3
            temp = head_ref;

            //Check if the MP3 is the last MP3. If not, change the field of the next node in the list
            if(head_ref->next != NULL)
            {
                //Sets the previous field of the next node in the list to the previous field of the node to be deleted
                head_ref->next->prev = head_ref->prev;
            }

            //Change the next pointer of the previous MP3 in the list to the MP3 following the one to be deleted
            head_ref->prev->next = head_ref->next;

            //Free the memory           
            free(temp->artist);
            free(temp->title);
            free(temp->date);
            free(temp);
        }

        //Traverse forward
        head_ref = head_ref->next;
    }
}

1 Ответ

0 голосов
/ 07 сентября 2018

В коде есть некоторые проблемы, но следующие два являются наиболее важными:

1.) Используйте strcmp для сравнения строк. head_ref->artist == artist сравнивает указатели, а не содержимое, и обычно маловероятно, что вы передадите тот же указатель, на который указывают элементы DLL.

2.) Если голова удалена, вам необходимо вернуть «новую» голову вызывающему абоненту deleteMP3; в противном случае переменная, переданная в deleteMP3, все еще будет содержать указатель на (удаленный) узел. Так что измените void deleteMP3(struct MP3* head_ref, char* artist) на struct MP3 *deleteMP3(struct MP3* head_ref, char* artist) и верните фактический заголовок DLL (независимо от того, изменен он или нет).

...