Моя программа выдает исключение при попытке удалить элемент из связанного списка - PullRequest
0 голосов
/ 02 мая 2019

У меня есть связанный список и две функции - одна для добавления, а другая для удаления участников из списка.Когда я пытаюсь удалить участника, я получаю исключение в функции удаления.

Исключение находится в строке

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

Исключение говорит -> Необработанное исключение в 0x50C4EF18 (ucrtbased.dll).) в файле singly_linked_list.exe: 0xC0000005: расположение чтения нарушения доступа 0xDDDDDDDD.произошло

Полная программа ниже -


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

Часть для добавления элемента в список выглядит следующим образом (вся функция) -

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

Ответы [ 3 ]

1 голос
/ 02 мая 2019

Вы недостаточно опубликовали, чтобы получить надлежащий анализ и помощь. Руководство по созданию полного, минимального примера не только для улыбок; часто сводя проблему к ее ядру, программист сам находит свою ошибку. Если нет, это дает отличное место для других. В любом случае, цикл в вашем удалении по сути:

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

Ваша бесплатная должна была выглядеть примерно так:

void *p = temp->next;
free(temp);
temp = p;
1 голос
/ 02 мая 2019
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{...}

Из этого фрагмента похоже, что temp_person_ptr указывает на что-то, но имя -> равно NULL. Добавьте оператор printf следующим образом перед вашим strcmp:

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

И вы увидите, что -> name равно null или что-то еще. удачи

0 голосов
/ 02 мая 2019

Это сработало, я не выходил из цикла while после освобождения и продолжал все время. Я добавил возврат к возвращению после того, как освободилось и размер списка уменьшился. Это работает сейчас.

...