Клонировать связанный список

#c #pointers #linked-list

Вопрос:

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#pragma warning(disable : 4996)


struct list_node
{
    char* name;
    struct list_node* contact;
    struct list_node* next;
};



struct list_node* create_list()
{
    struct list_node* nodes[10];
    int i;

    
    for (i = 0; i < 10; i  )
    {
        nodes[i] = (struct list_node*)malloc(sizeof(struct list_node));
    }

    
    for (i = 0; i < 9; i  )
    {
        nodes[i]->next = nodes[i   1];
    }
    nodes[9]->next = NULL;

    nodes[0]->name = (char*)malloc(strlen("John")   1);
    strcpy(nodes[0]->name, "John");
    nodes[0]->contact = nodes[1];

    nodes[1]->name = (char*)malloc(strlen("Mary")   1);
    strcpy(nodes[1]->name, "Mary");
    nodes[1]->contact = nodes[9];

    nodes[2]->name = (char*)malloc(strlen("Mohamed")   1);
    strcpy(nodes[2]->name, "Mohamed");
    nodes[2]->contact = nodes[0];

    nodes[3]->name = (char*)malloc(strlen("Liza")   1);
    strcpy(nodes[3]->name, "Liza");
    nodes[3]->contact = nodes[4];

    nodes[4]->name = (char*)malloc(strlen("Osenya")   1);
    strcpy(nodes[4]->name, "Osenya");
    nodes[4]->contact = nodes[4];

    nodes[5]->name = (char*)malloc(strlen("Peter")   1);
    strcpy(nodes[5]->name, "Peter");
    nodes[5]->contact = nodes[7];

    nodes[6]->name = (char*)malloc(strlen("Mahala")   1);
    strcpy(nodes[6]->name, "Mahala");
    nodes[6]->contact = nodes[2];

    nodes[7]->name = (char*)malloc(strlen("Rita")   1);
    strcpy(nodes[7]->name, "Rita");
    nodes[7]->contact = nodes[4];

    nodes[8]->name = (char*)malloc(strlen("Jacques")   1);
    strcpy(nodes[8]->name, "Jacques");
    nodes[8]->contact = nodes[8];

    nodes[9]->name = (char*)malloc(strlen("Paul")   1);
    strcpy(nodes[9]->name, "Paul");
    nodes[9]->contact = nodes[1];


    return nodes[0];
}


void print_list(struct list_node* l)
{
    int i = 0;
    while (l != NULL)
    {
        printf("Entry %d is %s, contact is %sn", i, l->name, l->contact->name);
        i  ;
        l = l->next;
    }
    printf("n");
}


struct list_node* copy_list(struct list_node* original)
{
    if (original == NULL)
    {
        return NULL;
    }

    else
    {
        struct list_node* tmp = (struct list_node*)malloc(sizeof(struct list_node));


        char a = (char)amp;(original->name);
        tmp->name = original->name;
        tmp->contact = original->contact;

        tmp->next = copy_list(original->next);

        return tmp;
    }
}


struct list_node* delete_list(struct list_node* l)
{
    struct list_node* tmp;
    while (l != NULL)
    {
        tmp = l->next;

        free(l->name);
        l->name = NULL;
        l->contact = NULL;
        l->next = NULL;

        free(l);

        l = tmp;
    }
    return NULL;
}

int main()
{
    struct list_node* original = NULL;
    struct list_node* copy = NULL;

    //create linked list
    original = create_list();

    //print linked list
    printf("Original:n");
    print_list(original);

    //copy linked list
    copy = copy_list(original);

    //delete original linked list
    original = delete_list(original);

    //print copy
    printf("Copy:n");
    //should print exactly the same thing as the original
    print_list(copy);
}
 

Я работал над некоторым кодом и не знаю, как подойти к проблеме. Мне дали весь этот код, кроме функции copy_list (), которую я должен был написать сам. При запуске кода мой компилятор дает мне ошибку исключения в 0x7BF71F4C (ucrtbased.dll) в lab2.exe: 0xc0000005 исключение: нарушение прав доступа чтения местоположения 0xDDDDDDDD. Я предполагаю, что это потому, что в главном копию связанного списка, и оригинал исключить; что смешивается с моей copy_list() устанавливается вызывает какие-то проблемы. Как бы я мог исправить это и изменить функцию copy_list ()?

Комментарии:

1. » Я не знаю, как подойти к проблеме «. Первое, что нужно сделать, это научиться эффективно отлаживать, чтобы вы могли сами найти проблему. Запустите свою программу в отладчике и/или добавьте инструкции печати отладки, чтобы отслеживать выполнение программы, чтобы определить, где происходит сбой и где все начинает идти не так. Как отлаживать небольшие программы .

2. tmp->name = original->name; Это просто указывает имя нового узла в ту же память, что и исходное имя. И эта память становится недействительной, когда исходный список удаляется. Вместо этого сделайте копию: tmp->name = strdup(original->name) . Аналогичная проблема для этой contact области.

3. Вы делаете поверхностную копию. То есть вы сохраняете исходные указатели. Таким образом, и поля name , и contact поля становятся недействительными после удаления исходного списка. В рамках копирования вам необходимо скопировать строки во вновь выделенное хранилище (легко), и вам нужно указать contact поля на скопированные узлы (сложнее, так как для этого требуется сопоставление старых узлов с новыми).