2017-01-06 6 views
0

現在、惑星シミュレーションを作成しており、惑星同士が衝突した場合に惑星を削除しようとしているときに問題が発生しています。C二重リンクリストの読み取りアクセス違反

現在ダブルリンクリストから要素を削除する際に問題が発生しています。その結果、読み取りアクセス違反が発生し、要素の1つが「0xFFFFFFFFFFFFFFFCB」でした。私は比較的新しいC言語なので、どこかで単に何かが見つからないと思う。

destroy()メソッドを使用せずにremove()メソッドを使用すると、エラーは発生しません。このメソッドはremove()メソッドをremove()メソッドとともに使用する場合にのみ発生し、時々それで。

のコードは、以下に添付されています

struct planet *head; //Head of list 
struct planet *tail; //Tail of list 

struct planet { 
    //Data 
    float mass; 
    struct planet *next; 
    struct planet *prev; 
}; 

planet *removeTail() { 
    struct planet* p = tail; 
    if (tail) { 
     if (head == tail) { 
      head = tail = 0; 
     } 
     else { 
      tail = tail->prev; 
      p->prev = 0; 
      tail->next = 0; 
     } 
    } 
    return p; 
} 

planet *removeHead() { 
    struct planet* p = head; 
    if (head) { 
     if (head == tail) { 
      head = tail = 0; 
     } 
     else { 
      head = head->next; 
      p->next = 0; 
      head->prev = 0; 
     } 
    } 
    return p; 
} 

planet *remove(struct planet* p) {//Breaking the tree 
    if (p == head) { 
     removeHead(); 
    } 
    else if (p == tail) { 
     removeTail(); 
    } 
    else { 
     p->prev->next = p->next; 
     p->next->prev = p->prev; 
    } 
    return p; 
} 

planet *destroy(struct planet* p) { 
    if (p) { 
     if (p != head || p != tail || (!p->next && p->prev)) { 
      delete p; 
      printf("Deleted\n"); 
      return 0; 
     } 
     else { 
      printf("Not deleted\n"); 
      return 0; 
     } 
    } 
} 

for (struct planet *p1 = head; p1 != 0; p1 = p1->next) 
{ 
    for (struct planet *p3 = head; p3 != 0; p3 = p3->next) 
     { 
      //Collision logic 
      if(p1 != p3){ 
       if(p1->mass >= p3->mass){ 
        destroy(remove(p3)); //Does not cause an error 
        break; 
       }else{ 
        destroy(remove(p1)); //Causes the error. 
        break; 
        //Deleting p1 here means the for loop can't move on 
       } 
      } 
     } 
} 

私はあなたが私に教えてください任意のより詳細な情報が必要な場合、私は、上記のすべての関連するコードが含まれていると信じています。私はまた、時にはシミュレーションが問題のないいくつかのノードを削除して削除することがあり、それ以外の場合は削除することができないという点で、何が原因でエラーが発生するのか正確にはわかりません。

アドバイスをいただければ幸いです。

planet *remove(struct planet* p) 
    if (p->prev == NULL) { 
     head = p->next; 
    } 
    else { 
     p->prev->next = p->next; 
    } 

    if (p->next == NULL) { 
     tail = p->prev; 
    } 
    else { 
     p->next->prev = p->prev; 
    } 
    return p; 
} 

と、おそらくどこかfree(p)があるはずです:

+0

コードサンプルでは使用していないため、これはopenglとしてタグ付けする必要はありません。 – SurvivalMachine

+0

実際には3つのループがありますが、私は誤って上記の2つしか表示していません。コードを修正します。 私はopenglタグも削除しました。私の謝罪です。 – Alex

+0

追加コードが追加されました。 – Alex

答えて

0

これはちょうど答えがある、問題は外側のforループがp3ループ内で壊れていたことでした。 p1は単にループを破壊しないように削除する必要があります。

1

削除コードは、単一の関数である可能性があります。

+0

それはもっと理にかなっていますが、クラスの講師は、頭と尾の削除を含む、LinkedListに含まれるいくつかのメソッドを見たいと思っています。 'free(p)'の使用に関して、それを扱う 'destroy()'メソッドでは 'delete p;'ではありませんか? – Alex

+0

@Alex C言語ではありません。 'delete'はありません。 – WhozCraig

+0

申し訳ありませんが、これをCとタグ付けしました。私が書いた関数は、二重リンクリストのどの要素に対しても機能しますが、反復を続けるとどうなるでしょうか。そして、 'p'のためのメモリをシステムに戻したら、(ループ制御のような)それを再び逆参照してはいけません。 –

関連する問題