Пишут что ошибка сегментирования , ошибка так понимаю находится в list_insert функции , заранее благодарю

Рейтинг: -1Ответов: 1Опубликовано: 11.08.2023
#include <stdlib.h>
#include <string.h>

// Объявление структур и функций (как в вашем коде)
int number_of_nod = 0; 
struct list_node_s;
        typedef struct list_node_s list_node_t;
        typedef struct list_node_s{
            list_node_t *prev;
            list_node_t *next;
            char name[30];
            char family[30];
            int age;
            double average_ball;
            int number;
        } list_node_t;
        
        typedef struct{
           list_node_t *first;
           list_node_t *last;
        }list_t;



int list_insert(list_t *list ,list_node_t *node, const char *name ,const char *family, int age, double average_ball)
        
        {
        list_node_t *new_node = calloc(1,sizeof(list_node_t));
        strcpy(new_node->name, name); // Копируем строку в поле name
        strcpy(new_node->family, family);
        new_node -> age = age;
        new_node -> average_ball = average_ball;
        new_node -> prev = node -> prev;
        new_node -> next = node;
        new_node -> number = number_of_nod;

        if (node->prev)
            node->prev->next = new_node;
            node -> prev = new_node;
        if (list->first == new_node)
            list->first = new_node;

        list_node_t *pointer = new_node -> next;
        while (pointer != NULL)
        {
            pointer ->number = ++number_of_nod;
            pointer = pointer -> next;
        }
        list -> last -> number = ++number_of_nod;
        
        
        return 0;  
          }





int list_push_back(list_t *list ,char *name ,const char *family, int age, double average_ball) {
          list_node_t *new_node = calloc(1, sizeof(list_node_t));
          strcpy(new_node -> name ,name);
          strcpy(new_node -> family , family);
          new_node -> age = age;
          new_node -> average_ball = average_ball;
          new_node -> number = number_of_nod++;

          new_node -> prev = list -> last;
          if (list -> last){
            list -> last-> next = new_node;
            }

            list -> last = new_node;
          if (!list->first)
             list -> first = new_node;
          return 0 ;
          } 




int main() {

int choice;

    
    list_t myList;  // Создаем экземпляр списка
    myList.first = NULL;  // Инициализируем первый и последний элементы списка
    myList.last = NULL;

    // Здесь пользовательский ввод для добавления узлов в список
    int numNodes;
    char name[30], family[30];
    int age;
    float average_ball;
    list_node_t *current = myList.first;
while (choice!=-1)
{
     
    printf("1. Создание узлов\n");
    printf("2. Вставка нового узла в конец списка\n");
    printf("3. Вывод списка\n");
    printf("4. Вcтавка узла в произвольное положение\n");
    printf("Ваш выбор: ");
    scanf("%d", &choice);

    if (choice == -1) {
            break;  // Выход из цикла, если выбран -1
        }



    switch (choice){
        case 1:
        printf("Вы выбрали создание узлов\n");
        printf("Введите количество узлов: ");
        scanf("%d", &numNodes);

        for (int i = 0; i < numNodes; i++) {
            

            printf("Введите данные для узла %d:\n", number_of_nod + 1);
            printf("Имя: ");
            scanf("%s", name);
            printf("Фамилия: ");
            scanf("%s", family);
            printf("Возраст: ");
            scanf("%d", &age);
            printf("Средний балл: ");
            scanf("%f", &average_ball);
            list_push_back(&myList, name, family, age, average_ball);
            }

        break;
        case 2:
            printf("вы выбрали вставку нового узла в конец списка,введите параметры узла %d:\n", number_of_nod+1);
            printf("Введите имя: ");
            scanf("%s", name);
            printf("Введите фамилию: ");
            scanf("%s", family);
            printf("Введите возраст: ");
            scanf("%d", &age);
            printf("Введите средний балл: ");
            scanf("%f", &average_ball);
            // Вставка нового узла в конец списка
            list_push_back(&myList, name, family, age, average_ball);
            break;
        case 3:
        printf("вывод списка\n" );
        // Вывод списка (по вашей логике вывода)
            list_node_t *current = myList.first;
            while (current != NULL) {
            printf("Имя: %s, Фамилия: %s, Возраст: %d, Средний балл: %5.2f, номер узла: %d\n",
                current->name, current->family, current->age, current->average_ball,current ->number);
            current = current->next;
            }
            break;
        case 4:
            printf("добавление узла перед каким-то другим\n");
            int number_nod = 0;
            scanf("номер введенного узла %d ",&number_nod);
            list_node_t *pointer = myList.first;
            for (int i = 0;i<number_nod;i++)
            {
                     pointer = pointer -> next;
            }
            printf("вы выбрали вставку нового узла ,введите параметры узла :\n");
            printf("Введите имя: ");
            scanf("%s", name);
            printf("Введите фамилию: ");
            scanf("%s", family);
            printf("Введите возраст: ");
            scanf("%d", &age);
            printf("Введите средний балл: ");
            scanf("%f", &average_ball);
            list_insert(&myList, current,name ,family,age,average_ball);
            break; 
        default:
            printf("некоректный вывод, идите нахуй!");
        }
}
        
        // Освобождение памяти (не забудьте освободить память для каждого узла)
        current = myList.first;
        while (current != NULL) {
            list_node_t *temp = current;
            printf("удален узел № %d:\n" , current->number);
            current = current->next;
            
            free(temp);
        }
        

    return 0;
}

Ответы

▲ 1

У тебя та же ошибка, что была и у меня: https://ru.stackoverflow.com/questions/1523205/Динамический-список-в-виде-структуры-в-языке-c

ответ в комментариях: strcpy() в list_insert не инициализирует объект, а значит, ты передаёшь данные на несуществующий адрес. Правда, у меня же строковое поле было указателем, а не массивом, т.к. придерживался динамического подхода. Инициализировать новую строку тогда нужно сначала malloc'ом:

char* newname = (char*) malloc(strlen(name) + 1);
if (newname) {
    strcpy(newname, name);
    free(name);
    new_node->name = newname;
}

Но, соответственно, менять придётся во всём коде массивы на указатели.

Я сам чайник, и обычно помалкиваю здесь. Но у тебя какие-то странные нагромождения в объявлении структуры. Долго вникал, но так и не понял, зачем ты дважды переименовал list_node_s в list_node_t. Поделился бы ты своим ресурсом - не шучу.

Да и целый код ты зря, наверное, сюда вывалил, тем более ещё и со странными комментариями, явно не твоего авторства. Кстати, пользуйся чаще переводчиком - ball остаётся мячом) можно было использовать point