2017-07-16 15 views
-2

最近Cプログラミングに戻り、私が書いているリンクリストの実装にいくつかの問題があります。リンクリストの実装を書くときのCポインタの問題

int linked_list_add_entry(linked_list** linked_list, void* data) 
{ 
    linked_list_entry* new = malloc(sizeof(linked_list_entry)); 
    ... 
    DPRINT("last(%p), new (%p)\n", (*linked_list)->last, new); 
    (*linked_list)->last->next = new; 
    DPRINT("(*linked_list)->last(%p)->next (%p)\n", (*linked_list)->last, (*linked_list)->last->next); 

デバッグ出力付:ここで問題のコードです

typedef struct linked_list_entry { 
    struct linked_list_entry *next; 
    struct linked_list_entry *prev; 
    void* data; 
} linked_list_entry; 

typedef struct linked_list { 
    uint32 count; 
    struct linked_list_entry *first; 
    struct linked_list_entry *last; 
} linked_list; 

:ここ

は私の構造定義されている

data-types/linked-list.c:37:linked_list_add_entry(): last(0x7fa497402790), new (0x7fa4974027b0) 
data-types/linked-list.c:39:linked_list_add_entry(): (*linked_list)->last(0x7fa4974027b0)->next (0x0) 

任意のアイデアは、なぜ新しいへの最後のポインタの変更新しいポインタがNULLに変更されますか?

おかげ

+0

^新しい^予約語ではありませんか? – MKR

+3

@ManojKumarRaiいいえ、 'new'はCの予約語ではありません.C++と混同しています。 – Gilles

+0

'* linked_list'ポインタの値は何ですか?ダンプに追加してください。 'linked_list'にどのようにメモリを割り当てますか? – AnT

答えて

-3

答えはmalloc関数を使用しているとき、私は構造体キーワードを使用するために必要なことです:あなたが提供

linked_list_entry* new = malloc(sizeof(struct linked_list_entry)); 
+3

ええと...なぜ? 'linked_list_entry'は完全に有効な型名です。 – AnT

+3

あなたが示したコードとの違いはありません。別のバージョンのコードを実行していた可能性はありますか? – Gilles

+0

それは、私が書いた次のテストを参照してください: printf( "%d対%dの\ n"、sizeof(linked_list)、sizeof(struct linked_list))); 8対24 奇妙な! – Jason

3

ダンプは、あなたが

(*linked_list)->last->next = new; 
をした後 (*linked_list)->lastの値が変更されたことを示しています

しかし、このコード行は(*linked_list)->lastに変更されません(少なくとも、これは想定されていません)。そのような "魔法" の行動のための

の説明が可能で

  1. **linked_listが適切に割り当てられていない含まれています。メモリが少なすぎると、 **linked_listオブジェクトに割り当てられます。その結果、*(*linked_list)->lastは、メモリ位置が**linked_listに重なってしまいます。このため、上記の割り当てが(*linked_list)->lastに変更されているように見えます。私。前述のポインタ問題のために(*linked_list)->last(*linked_list)->last->nextはメモリ内の同じ場所を占有します。

    オブジェクトにメモリの量が正しく割り当てられていない(不十分な)場合などです。その場合、問題は呼び出しコードにあります。入力として「壊れた」リストを提供します。

    呼び出しコードがlinked_listのメモリをどのように割り当てますか?このファンクションでは、ファンクション・パラメータにはlinked_listという名前を使用したため、タイプlinked_listの名前は表示されません。 linked_listオブジェクト自体を割り当てた「他の」関数でそのようなことをした場合、sizeof(linked_list)を使用しようとすると、不正な値(struct型の代わりにポインタのサイズ)が返されます。それは記憶の不足を説明するでしょう。

  2. (*linked_list)->lastは正しく初期化されたポインタではありません。予期せぬ場所を指しています。結果として、*(*linked_list)->lastは、**linked_list等(上記参照)のメモリ位置と重複してしまう。

  3. 実行していたコードは、ここに投稿したコードではありません。

関連する問題