У меня есть общая реализация двусвязного списка, и я работал над вставкой. После вставки я пытаюсь перебрать список в обратном направлении, начиная с ноги, и получаю ошибку шины Чтобы протестировать код и попытаться изолировать ошибку, в которую я поместил операторы print (не самая лучшая процедура отладки, но полезная для того, чтобы с первого взгляда сказать мне, что делает мой код). Чтобы попытаться выяснить, где возникает проблема, после каждой вставки я спрашиваю значение второго-последнего элемента в списке. Я всегда вставляю элементы в порядке 5, 2, 10, 80, 4, 1, 7, 8, и после вставки 4 в список он последовательно задыхается. Полный код программы приведен ниже.
dlist_t *
insert_in_order (dlist_t *list, void *value, size_t size,
int (*cmp_fptr)(const void *, const void *))
{
dlnode_t * prev = NULL;
dlnode_t * current = list->head;
dlnode_t * newnode = safe_malloc(sizeof(dlnode_t));
newnode->data = value;
newnode->next = NULL;
newnode->prev = NULL;
printf("Beginning list loop for %d.\n", *(int *) newnode->data);
while (current != NULL && cmp_fptr(newnode->data, current->data) != -1)
{
prev = current;
current = current->next;
}
printf("Insertion point found.\n");
newnode->next = current;
newnode->prev = prev;
if (prev == NULL)
{
printf("Setting for new head\n");
list->head = newnode;
}
else
{
printf("Setting previous next to new node\n");
prev->next = newnode;
}
if (current == NULL)
{
printf("setting for new foot.");
list->foot = newnode;
}
else
{
printf("Setting for new current previous\n");
current->prev = newnode;
}
list->list_len++;
list->size = sizeof(list);
printf("Insertion compete for %d\n\n", *(int *) newnode->data);
printf("Data for surrounding:\n");
if(newnode->next !=NULL)
{
printf("Next is %d \n", *(int *) newnode->next->data);
}
if(newnode->prev != NULL)
{
printf("Prev is %d \n\n", *(int *) newnode->prev->data);
}
if(list->foot->prev != NULL)
{
printf("Gonna print secondlast!\n");
printf("secondlast is%d \n\n", *(int *)list->foot->prev->data);
}
return list;
}
Определения списка очень просты, просто
struct dlnode
{
void *data; /* A pointer to a generic satellite data payload */
dlnode_t *next; /* A pointer to the next item in the list */
dlnode_t *prev; /* A pointer to the previous item in the list */
};
typedef struct
{
dlnode_t *head; /* A pointer to the head node of the list */
dlnode_t *foot; /* A pointer to the foot node of the list */
int list_len; /* Total number of items in the list */
int size; /* Size of the list in bytes */
} dlist_t;
Вы можете изменить определение функции по своему усмотрению, а safe_malloc - это просто ярлык для malloc, который можно заменить, если вы сами тестируете код. cmp_fptr - указатель на функцию для простого метода «больше, чем b».
РЕДАКТИРОВАТЬ: ОБНОВЛЕНИЕ
Линия
printf("secondlast is%d \n\n", *(int *)list->foot->prev->data);
это то, что заставляет программу останавливаться, я использовал отладчик. При вставке элементов в список он останавливается в этой строке после нескольких вставок.
Ниже приведен мой тестовый код, который я сейчас использую.
int *
alloc_data (int val)
{
int *rv = safe_malloc (sizeof (int));
*rv = val;
return (rv);
}
int
main (void)
{
dlist_t *list = NULL;
int *num = NULL, *rv = NULL;
dlnode_t *tnode = NULL;
list = make_empty_list ();
list = insert_in_order (list, alloc_data (5), sizeof(int), cmp_int);
list = insert_in_order (list, alloc_data (2), sizeof(int), cmp_int);
list = insert_in_order (list, alloc_data (10), sizeof(int), cmp_int);
list = insert_in_order (list, alloc_data (80), sizeof(int), cmp_int);
list = insert_in_order (list, alloc_data (4), sizeof(int), cmp_int);
list = insert_in_order (list, alloc_data (1), sizeof(int), cmp_int);
list = insert_in_order (list, alloc_data (7), sizeof(int), cmp_int);
list = insert_in_order (list, alloc_data (8), sizeof(int), cmp_int);
return(EXIT_SUCCESS);
}
Есть немного больше, но это все, что я сейчас тестирую.
Спасибо за подсказку по списку -> размеру, я не совсем уверен, что я думал об этом изначально.
edit2: спасибо за поиск ошибок safe_malloc, я думал, что это было причиной проблемы, но я все еще получаю ту же ошибку. Отладчик выдает мне sigsegv (ошибка сегментации) после вставки 4, и он попадает в строку, где для здравого смысла я запрашиваю список-> foot-> prev-> data (см. Выше).
Окончательное редактирование: проблема решена путем правильного неправильного размещения достаточно места для данных узла. Спасибо тем, кто помог. В моем коде есть другие проблемы, но они лучше всего подходят для другого вопроса и для другого фрагмента кода.