简体   繁体   中英

Deleting a structure from a doubly linked list based on its contents (in C)

My program is a basic C interface that allows the user to enter, print forwards, print backwards and delete MP3 records from a list. The list is implemented as a doubly linked list of MP3 structures in the C language.

All my functions except Delete work fine. Delete takes in a pointer to the head node of the list and a character string signifying which artist's records you would like deleted. In my main I record the user input and have verified it is being recorded correctly. Then I pass the user input and the head reference into the following function to delete said MP3 records. However, my program builds and executes fine but does not actually delete any records when the delete function is called. Any help is appreciated.

For clarity, I have looked at multiple questions on stack regarding deleting nodes from a DLL, however they all are regarding simple DLL holding integer values and don't seem to translate well to my scenario. I apologize if this is considered a duplicate question, if so, please point me to the question I am duplicating. Thanks again for any and all assistance. Below is my function

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;
    }
}

There are some issues in the code, but the following two are the most critical ones:

1.) use strcmp to compare strings. head_ref->artist == artist compares the pointers, not the contents, and it's usually unlikely that you pass in the same pointer to which the DLL elements point to.

2.) if the head is deleted, you need to pass back the "new" head to the caller of deleteMP3 ; otherwise the variable passed to deleteMP3 will still hold a pointer to the (deleted) node. So change void deleteMP3(struct MP3* head_ref, char* artist) to struct MP3 *deleteMP3(struct MP3* head_ref, char* artist) and return the actual head of the DLL (whether changed or not).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM