打印双链接列表访问冲突

时间:2012-04-24 14:40:54

标签: c linked-list access-violation

我需要一些帮助来弄清楚为什么我会遇到此访问冲突。这是家庭作业,我已将其全部写入,但在打印列表时最终会出现访问冲突。我正在尝试向前和向后打印列表。我怀疑问题在于反向功能。这是代码并感谢您的帮助。

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个链接列表的不同示例,并搜索了论坛 为了回答我的问题。我尝试使用反转列表的每个示例似乎都没有做任何事情或最终导致此访问冲突错误。哦,是的,主文件或头文件中没有任何内容可以更改。

3 个答案:

答案 0 :(得分: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中,你交换了一些previousnext指针,然后

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

在某些时候将last设置为未初始化的非NULL指针,这会导致访问冲突。

答案 1 :(得分: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;
    }
}

答案 2 :(得分:0)

以下是调试此问题的一些建议。

1)修改源代码以打印调试语句。您甚至可以根据#ifdef DEBUG_STATEMENTS标志编译出调试信息。

2)您可以使用调试器并在程序崩溃之前逐步执行此操作和/或设置断点。如果程序不是守护程序/系统服务或驱动程序,调试器将很容易工作。

其他建议我实际上更多地围绕实现而不是调试,并且与预分配内存和在预分配内存中操作链表有关。但是,因为这比前两个建议更复杂,所以我将停止对这个想法的概述。

祝你好运。