2011-08-11 4 views
1

二重リンクリストの汎用実装があり、挿入作業中だった。挿入後、私は足から始まってリストを逆向きに反復しようとします。バスエラーが発生します。コードをテストし、エラーを特定しようとすると、私はprint文を入れました(最良のデバッグ手順ではありませんが、私のコードが何をしているかを一目瞭然に伝えるのに便利です)。問題がどこで発生するかを調べるために、挿入するたびに、リストの最後の2番目の要素の値を求めます。私は常に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は、単純な 'is a greater than b'メソッドへの関数ポインタです。

EDIT:UPDATE

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のエラー終了のおかげで、私はそれが問題の原因だと思ったが、私はまだ同じエラーが発生する。デバッガは、4が挿入された後、私にsigsegv(セグメンテーションフォールト)を与え、それがlist-> foot-> prev-> data(上記を参照)を聞いてきた行に行きます。

最終編集:ノードデータ用に十分なスペースを適切に割り当てて問題を解決しました。助けてくれた人に感謝します。私のコードには他にも問題がありますが、それは別の質問に適しており、別のコードスニペットにも適しています。

+2

デバッガでこれを実行してみませんか?これにより、どの行でエラーが発生するかがわかり、変数の値などを調べることができます。 –

+0

あなたのコードは 'list-> size = sizeof(list);'とは離れてかなり穏やかに見えます。 (ofcourse 'if(list-> foot-> prev!= NULL)'も 'list-> foot == NULL'のときにはうまくいきません)。 @Oliのようにデバッガを使って実行し、さらにコードを投稿してください。 – user786653

答えて

1

いくつかのこと:

それはすでに述べたとおり、list->size = sizeof(list);は、おそらくあなたは、引数として渡されたsize_t sizeは、おそらくあなたの主な問題であり、危険なようだ

(この変数は何だと思う何をしません。関数を呼び出す値?)

間違ったサイズでdlnode_t * newnode = safe_malloc(size);を行うには、あなたの問題を説明することができ

dlnode_t * newnode = safe_malloc(size);

はおそらく

dlnode_t * newnode = safe_malloc(sizeof(dlnode_t));

最終に置き換える必要があり、あなたのリストには、あなたが直接void *valueはなくそのコピーを使用しています。 この関数を常に同じブロックで呼び出さない場合は、問題が発生します。

同じ関数シグネチャを使用すると、sizeパラメータの値をmalloc/memsetにする必要があります。それをあなたのリストに保存してください

+0

アドバイスをいただきありがとうございます。私は自分のコードを修正し、誰もが見ることができるように多くを投稿しました。私はまだエラーが発生しています。私はリスト - >サイズで本当に何をやっていて、それを更新すべきかを知らないことに私の無知を認めます。 – buggritall