2012-04-24 2 views
0

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

list.h

typedef int Titem; 

// Interface of list 
typedef struct node *Tpointer; 
typedef struct node 
{ 
    Titem item; 
    Tpointer next, previous; 
} Tnode; 

typedef struct 
{ 
Tpointer first; 
Tpointer last; 
}Tdbl; 


void initialize_dbl (Tdbl *list); 
void insert_to_dbl_front (Tdbl *list, Titem data); 
void insert_to_dbl_back (Tdbl *list, Titem data); 
void print_dbl (Tdbl const list); 
void print_dbl_reverse (Tdbl const list); 

list.c

#include <stdio.h> 
#include <stdlib.h> 
#include "List.h" 

#define TYPE_INT 0 
#define TYPE_FLOAT 1 



// Implementation of list (only obj is need in appl) 
void initialize_dbl (Tdbl *list) 
{ 
    list->first = NULL; 
    list->last = NULL; 
} 


void insert_to_dbl_front (Tdbl *list, Titem data) 
{ 
    Tpointer newnode; 

    if(list->first == NULL) 
    { 
     newnode = (Tpointer) malloc(sizeof(Tnode)); 
     newnode->item = data; 
     newnode->next = NULL; 
     newnode->previous = NULL; 
     list->first = newnode; 
    } 
    else 
    { 
     newnode = (Tpointer) malloc(sizeof(Tnode)); 
     newnode->item = data; 
     newnode->next = list->first; 
     newnode->previous = NULL; 
     list->first = newnode; 

    } 
} 

void insert_to_dbl_back (Tdbl *list, Titem data) 
{ 
    Tpointer newnode; 

    newnode = (Tpointer) malloc(sizeof(Tnode)); 
    newnode -> item = data; 
    if (list->first == NULL) 
     list->first = newnode;  //first node 
    else 
     list->last->next = newnode; //not first node 
    list->last = newnode; 
    list->last->next = NULL; 
} 

void print_dbl (Tdbl const list) 
{ 
    Tpointer what; 

    printf("\nList forward:"); 
    what = list.first; 
    while (what != NULL) { 
     printf("%d ", what->item); 
     what = what->next; 
    } 

} 


void print_dbl_reverse (Tdbl const list) 
{ 
    Tpointer last = list.last; 
    Tpointer temp = NULL; 

    printf("\nList reversed: "); 
    if(last == NULL) 
    { 
     printf(""); 
    } 
    else 
    { 
     while(last != NULL) 
     { 
      temp = last->next; 
      last->next = last->previous; 
      last->previous = temp; 
      last = temp; 

     } 

     printf("\nList reverse:"); 

     while (last != NULL) 
     { 
      printf("%d ", last->item); 
      last = last->next; 
     } 
    } 
} 

main.c

#include "list.h" 
#include <stdio.h> 


int main(void) { 
Tdbl dbl; 
initialize_dbl(&dbl); 
print_dbl(dbl); 
print_dbl_reverse(dbl); 
insert_to_dbl_back(&dbl, 10); 
print_dbl(dbl); 
print_dbl_reverse(dbl); 
insert_to_dbl_front(&dbl, 20); 
print_dbl(dbl); 
print_dbl_reverse(dbl); 
insert_to_dbl_back(&dbl, 30); 
print_dbl(dbl); 
print_dbl_reverse(dbl); 
insert_to_dbl_front(&dbl, 40); 
print_dbl(dbl); 
print_dbl_reverse(dbl); 
insert_to_dbl_back(&dbl, 50); 
print_dbl(dbl); 
print_dbl_reverse(dbl); 


fflush(stdin); getchar(); 
} 

Я просмотрел около 10 различного экзамена ссылки связанных списков, а также на форуме для ответа на мой вопрос. Каждый пример, который я попытался сделать с изменением списка, кажется, ничего не делает или заканчивается этой ошибкой нарушения прав доступа. О да, ничто в главном или заголовочном файле не может быть изменено.

+0

Добро пожаловать в SO! Вы хотите, чтобы сообщество SO отлаживало ваш код? – vyegorov

+0

Сторона примечания: 'fflush (stdin);' undefined до C. – FatalError

+0

Это поможет увидеть «эту ошибку нарушения доступа» – smocking

ответ

0

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

#include <stdio.h> 
#include <stdlib.h> 
#include "List.h" 

#define TYPE_INT 0 
#define TYPE_FLOAT 1 



// Implementation of list (only obj is need in appl) 
void initialize_dbl (Tdbl *list) 
{ 
    list->first = NULL; 
    list->last = NULL; 
} 


void insert_to_dbl_front (Tdbl *list, Titem data) 
{ 
    Tpointer newnode = (Tpointer) malloc(sizeof(Tnode));; 
    newnode->item = data; 
    newnode->previous = NULL; 
    newnode->next = list->first; 

    if(list->first != NULL) 
     list->first->previous = newnode; 
    else 
     list->last = newnode; 

    list->first = newnode; 
} 

void insert_to_dbl_back (Tdbl *list, Titem data) 
{ 
    Tpointer newnode = (Tpointer) malloc(sizeof(Tnode)); 
    newnode->item = data; 
    newnode->next = NULL; 
    newnode->previous = list->last; 

    if (list->first == NULL) 
     list->first = newnode; 
    else 
     list->last->next = newnode; 

    list->last = newnode; 
} 

void print_dbl (Tdbl const list) 
{ 
    Tpointer what; 

    printf("\nList forward: "); 
    what = list.first; 
    while (what != NULL) { 
     printf("%d ", what->item); 
     what = what->next; 
    } 
} 


void print_dbl_reverse (Tdbl const list) 
{ 
    Tpointer last = list.last; 
    Tpointer temp = last; 

    printf("\nList reverse: "); 
    while (last != NULL) 
    { 
      last = last->previous; 
    } 
} 
1

В

void insert_to_dbl_front (Tdbl *list, Titem data) 
{ 
    Tpointer newnode; 

    if(list->first == NULL) 
    { 
     newnode = (Tpointer) malloc(sizeof(Tnode)); 
     newnode->item = data; 
     newnode->next = NULL; 
     newnode->previous = NULL; 
     list->first = newnode; 
    } 

вы не установили list->last, так что все еще находится в NULL. Однако, если list->first не NULL,

else 
{ 
    newnode = (Tpointer) malloc(sizeof(Tnode)); 
    newnode->item = data; 
    newnode->next = list->first; 
    newnode->previous = NULL; 
    list->first = newnode; 

} 

вы никогда не установить previous указатель текущего первого узла на новый узел, так что вы на самом деле не имеют дважды связанный список.

И когда вы вставляете на спине,

void insert_to_dbl_back (Tdbl *list, Titem data) 
{ 
    Tpointer newnode; 

    newnode = (Tpointer) malloc(sizeof(Tnode)); 
    newnode -> item = data; 
    if (list->first == NULL) 
     list->first = newnode;  //first node 
    else 
     list->last->next = newnode; //not first node 
    list->last = newnode; 
    list->last->next = NULL; 
} 

Вы никогда не установите previous указатель на новый узел. Таким образом, у вас все еще есть только один связанный список. Это само по себе не приведет к нарушению доступа, но здесь вы никогда не устанавливали newnode->previous на что-либо, поэтому он содержит любые биты, находящиеся в этой ячейке памяти.

Тогда в print_dbl_reverse вы поменять некоторые previous и next указатели и имеют

while (last != NULL) 
{ 
    printf("%d ", last->item); 
    last = last->next; 
} 

в какой-то момент, который устанавливает last к неинициализированной не- NULL указателя, что приводит к нарушению прав доступа.

0

Вот несколько предложений по отладке этой проблемы.

1) Измените исходный код, чтобы печатать отладочные операторы. Вы даже можете получить отладочную информацию, собранную на основе флага DEIF_G_STATEMENTS #ifdef.

2) Вы можете использовать отладчик и пройти через это и/или установить контрольные точки непосредственно перед сбоем программы.Отладчик будет работать легко, если программа не является демоном/системным сервисом или драйвером.

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

Удачи.

+0

Спасибо за все ваши ответы. Я использую отладку в vs 10, чтобы пройти через нее. Но не мог понять, что происходит. Я попробую предложения и дам вам знать, что я придумал. – Xintaris

 Смежные вопросы

  • Нет связанных вопросов^_^