My program is throwing an exception trying to delete an element from a linked list

-1

I have a linked list and two functions - one to add and other to delete members from the list. When I try to delete a member I am getting an exception in the delete function.

The exception is in line

if (strcmp((temp_person_ptr->name), name_to_remove))

The exception says -> Unhandled exception at 0x50C4EF18 (ucrtbased.dll) in singly_linked_list.exe: 0xC0000005: Access violation reading location 0xDDDDDDDD. occurred

Full program is below -


#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include "globals.h"

extern struct person* starting_address;

struct person* delete_person(size_t* list_size_ptr, struct person* ptr_current_person)
{
    printf("There are %u items in list \n", *list_size_ptr);

    struct person* temp_person_ptr = starting_address, *to_save_person_ptr;
    printf("The items in list are \n");
    while (temp_person_ptr)
    {
        printf("%s \n", temp_person_ptr->name);
        temp_person_ptr = temp_person_ptr->next_person_ptr;
    }

    char name_to_remove[MAX_NAME_LENGTH];
    printf("Please enter the name to remove \n");
    gets_s(name_to_remove, MAX_NAME_LENGTH - 1);

    temp_person_ptr = starting_address;
    to_save_person_ptr = starting_address; // Not required by logic - just to initialize for compiler
    while (temp_person_ptr)
    {
        if (strcmp((temp_person_ptr->name), name_to_remove))
        {
            to_save_person_ptr = temp_person_ptr;
            temp_person_ptr = temp_person_ptr->next_person_ptr;
        }
        else
        {
            // Since we are going to remove temp_person_ptr - we save it's next person_ptr in preceding person which is to_save_person_ptr
            // Only if the person_ptr to be removed is NOT the first person
            // For now - assume - one element name will match
            if (temp_person_ptr != starting_address)
                to_save_person_ptr->next_person_ptr = temp_person_ptr->next_person_ptr; // takes care if temp_person_ptr is the last one as well
            else // Else the next person's address is the new starting address
                starting_address = temp_person_ptr->next_person_ptr;

            free(temp_person_ptr);
            (*list_size_ptr)--;
        }
    }
    return (ptr_current_person);
}

The part to add an element to the list looks as below (entire function) -

struct person* add_person(size_t* list_size_ptr, struct person* ptr_current_person)
{

    struct person *ptr_new_person;

    ptr_new_person = (struct person*) malloc(sizeof(struct person));

    // If first person- its starting address is the starting address of list
    if ((*list_size_ptr) == 0)
    {
        starting_address = ptr_new_person;
    }
    else
    {
        //1. Add the new address to the chain - only if this is not the first person
        ptr_current_person->next_person_ptr = ptr_new_person;
    }
    ptr_new_person->next_person_ptr = NULL;

    printf("Please enter the name \n");
    gets_s(ptr_new_person->name, MAX_NAME_LENGTH - 1);

    // 2. We may make ptr_new_person as ptr_current_person
    ptr_current_person = ptr_new_person;
    // 3. Now onwards ptr_current_person refers to the pointer to the newly added person

    (*list_size_ptr)++;
    return (ptr_current_person);
}

c
linked-list
dynamic-memory-allocation
asked on Stack Overflow May 2, 2019 by Bhawandeep Singh • edited May 2, 2019 by Bhawandeep Singh

3 Answers

1
while (temp_person_ptr)
{
    if (strcmp((temp_person_ptr->name), name_to_remove))
    {
        to_save_person_ptr = temp_person_ptr;
        temp_person_ptr = temp_person_ptr->next_person_ptr;
    }
    else{...}

From this snippet it looks like temp_person_ptr is pointing to something, but the ->name is NULL. Add a printf statement like this before your strcmp:

if(!(temp_person_ptr->name)){
      printf("This is why your segfaulting\n");
    }

And you will either see that ->name is null or its something else. good luck

answered on Stack Overflow May 2, 2019 by Bwebb
1

You haven't posted enough to get a proper analysis and help. The guidance for making a complete, minimal example isn't just for grins; often by reducing a problem to its core, the programmer finds their error themselves. If not, it gives a great place for other to. Regardless, the loop in your delete is essentially:

temp = start;
while (temp) {
    if (strcmp(temp->name, name)) {
         temp = temp->next;
    } else {
         free(temp);
    }
}

Your free should likely have been something like:

void *p = temp->next;
free(temp);
temp = p;
answered on Stack Overflow May 2, 2019 by mevets
0

It worked, I was not exiting the while loop after free and going on all the way. I added a return to return after free is done and list size is decremented. It works now.

answered on Stack Overflow May 2, 2019 by Bhawandeep Singh

User contributions licensed under CC BY-SA 3.0