#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
поля на скопированные узлы (сложнее, так как для этого требуется сопоставление старых узлов с новыми).