我需要一些帮助来弄清楚为什么我会收到这种访问违规。这是家庭作业,我都写好了,但最终在打印列表时遇到访问冲突。我正在尝试正向和反向打印列表。我怀疑问题出在反向功能上。这是代码,感谢您的帮助。
列表.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);
列表.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;
}
}
}
主.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 个不同的链表示例,并搜索了论坛以回答我的问题。我尝试反转列表的每个示例似乎都无济于事,或者最终出现此访问违规错误。哦,是的,主文件或头文件中的任何内容都无法更改。
in
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
指针,这会导致访问冲突。
你的代码中有很多错误。我写了一个简单的,所以你可以研究它,但把写反向功能留给你。玩得愉快!
#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) 修改源代码以打印调试语句。您甚至可以根据 #ifdef DEBUG_STATEMENTS 标志编译调试信息。
2) 您可以使用调试器并在程序崩溃之前单步执行此操作和/或设置断点。如果程序不是守护程序/系统服务或驱动程序,调试器将轻松工作。
我实际上围绕实现而不是调试的其他建议,并且与预分配内存和在预分配内存中操作链表有关。但是,由于这比前两个建议更复杂,因此我将停止对该想法的概述。
祝你好运。