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 の異なる例を見ただけでなく、私の質問に対する回答をフォーラムで検索しました。リストを逆にして試したすべての例は、何もしないように見えるか、このアクセス違反エラーで終わります。そうそう、メイン ファイルまたはヘッダー ファイルは何も変更できません。

4

3 に答える 3

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新しいノードのポインターを設定することはありません。したがって、まだ単一リンクリストしかありません。それだけではアクセス違反は発生しませんが、ここでは any に設定newnode->previousないため、そのメモリ位置にたまたまあったビットが含まれます。

次に、いくつかのポインターprint_dbl_reverseを交換して、previousnext

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

ある時点でlast、初期化されていない非NULLポインターに設定され、アクセス違反が発生します。

于 2012-04-24T15:44:17.823 に答える
0

この問題をデバッグするためのいくつかの提案を次に示します。

1) デバッグ ステートメントを出力するようにソース コードを変更します。#ifdef DEBUG_STATEMENTS フラグに基づいてデバッグ情報をコンパイルすることもできます。

2) デバッガーを使用して、これをステップ実行したり、プログラムがクラッシュする直前にブレークポイントを設定したりできます。プログラムがデーモン/システムサービスまたはドライバーでない場合、デバッガーは簡単に動作します。

その他の提案 私は、デバッグよりも実装を中心に展開しており、メモリの事前割り当てと、事前割り当てメモリ内でのリンク リストの操作に関係しています。ただし、これは最初の 2 つの提案よりも複雑なので、そのアイデアの概要にとどめます。

幸運を。

于 2012-04-24T15:56:12.863 に答える
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;
    }
}
于 2012-04-24T15:41:56.987 に答える