1

そのため、XOR リンク リストを作成しています。新しいノードにメモリを割り当てようとすると、プログラムがクラッシュします。挿入関数のコードは次のとおりです。

void add(DataType value, XORList ** xlist)
{
    XORListNode * node;
    node = ( XORListNode* )malloc( sizeof (XORListNode) );
    printf("node memory allocated\n");

    if ((*xlist)->head->prevPNext == NULL && (*xlist)->tail->prevPNext == NULL) //XOR linked list is empty: [ H - T ] + N => [ H<->T<->N ] => [ H<->A<->T ]
    {
        node->prevPNext = (*xlist)->tail; //new element points to tail
        (*xlist)->tail->prevPNext = ( XORListNode * )( (uintptr_t)(*xlist)->head ^ (uintptr_t)(*xlist)->tail ); //tail points to head and new value
        (*xlist)->head->prevPNext = (*xlist)->tail;

        (*xlist)->tail->value = value;
        (*xlist)->tail = node;
    }
    else    //Otherwise: [ H<->A<->B<-...->X<->T ] + N => [ H<->A<->B<-...->X<->T<->N ] => [ H<->A<->B<-...->X<->Y<->T ]
    {
        node->prevPNext = (*xlist)->tail;
        (*xlist)->tail->prevPNext = ( XORListNode * )( (uintptr_t)(*xlist)->tail->prevPNext ^ (uintptr_t)node );

        (*xlist)->tail->value = value;
        (*xlist)->tail = node;
    }
}

これは XORList の定義です:

typedef struct XORList
{
    XORListNode * head, * tail;
} XORList;

そして、これは XORListNode の定義です:

typedef struct XORListNode
{
    DataType value;
    struct XORListNode * prevPNext;
} XORListNode;

私はまだポインターの経験がないので、コードに関する他のコメントもいただければ幸いです。

ご協力ありがとうございました。

4

1 に答える 1

0

これmallocは実装の問題ではありません。最初の 3 行を除く関数の本体全体を削除することで、これをテストできます。

Sourav Ghosh が指摘したように、主な問題はif-clause でこれらのポインターを使用する前にxlist、 、*xlist(*xlist)->headまたはが NULL かどうかを確認しないことです。(*xlist)->tailif ((*xlist)->head->prevPNext == NULL && (*xlist)->tail->prevPNext == NULL)

したがって、「初期化されていない」リストがあり、head(またはそれらを設定していない場合は、それらの値のような値または完全に未定義の何かになる) 場合、アクセス違反が発生します。アプリケーションで利用できます。tailNULLNULL0xcccccccc

これを修正するには、add 関数で次のケースを処理する必要があります。

void add(DataType value, XORList ** xlist)
{
    XORListNode * node;

    if ((xlist == NULL) || ((*xlist) == NULL))
    {
        printf("INVALID INPUT (xlist)\n");
        return;
    }

    node = ( XORListNode* )malloc( sizeof (XORListNode) );
    if (node == NULL)   // always check return values
    {
        printf("FAILED TO ALLOCATE !!!\n");
        return;
    }

    if (((*xlist)->head != NULL) && ((*xlist)->tail != NULL))
    {
        /* your current implementation goes here */
    }
    else
    {
        /*
        ** no item within list, yet!
        ** - initialize head and tail attributes of *xlist
        ** - set node->prevPNext to NULL
        */
    }
}

さらに3つのこと:

  • メンバーとメンバーが NULLXORListであることを保証するゼロ関数を構造体に実装することを強くお勧めします。それ以外の場合、それらは初期化されておらず、NULL であるかどうかのチェックは機能せず、アクセス違反が再び発生しています。headtail
  • XORList関数内で二重ポインタを使用するのはなぜaddですか? 投稿したコードには単一のポインターで十分です。
  • malloc場合によっては失敗する可能性があるため、 function の戻り値を実装する必要がありますadd。そうしないと、呼び出し元は追加が成功したかどうかを知ることができません。の値を返すだけですnode。関数が失敗した場合、戻り値はNULL、成功した場合はゼロ以外です。
于 2015-05-09T18:42:33.430 に答える