2017-01-06 18 views
0

私は、重力リンクや複数のループを使用して力や衝突などを計算する惑星シミュレーションを作成しています。私が抱えている問題は、衝突のために惑星を削除しようとすると、読み取りアクセス違反エラーです。LinkedListをループする際の読み取りアクセス違反

衝突をチェックすると、2つの惑星のうちの小さい方が削除されます。私が書いた方法は、方程式中の小さい方の惑星が、包囲ループからのものであることです。

新しいCの組み合わせ。同じ問題を今何日も見つめている。クラスの講師が私たちにC/C++ハイブリッドを使用させているということは、問題を解決する効率的な方法を考えるのに苦労しています。ループを外に出すことで問題は解決しましたが、シミュレーションのパフォーマンスに大きな影響を与えます。

コードは以下見ることができます:私は探しています何

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

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

planet *remove(struct planet* p) {//Breaking the tree 
    if (p == head) { 
     removeHead(); //Method not included in sample due to size and it is sound. 
    } 
    else if (p == tail) { 
     removeTail();//Method not included in sample due to size and it is sound. 
    } 
    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 
        } 
       } 
      } 
    } 

は、効率的かつループを壊すことなく、P1を削除する方法についていくつかのアドバイスです。

ご協力いただきまして誠にありがとうございます。

+2

あなたの講師は、「new」と「delete」を除いてCを教えています。ああ。 – Zeta

+1

恐ろしい奇妙な組み合わせは別として、なぜ 'destroy'は戻り値を持っていますか?それが返すのは、とにかく0ですが、まったくリターンがないかもしれませんか? – UnholySheep

+0

しかし、何らかの理由で、何らかの理由で彼はテクスチャのために 'malloc'にデフォルト設定されています... – Alex

答えて

2

p1が破棄されたときに内側ループが切断され、外側ループが破られることはありません。この場合、ループ制御によって参照が解除された後、削除されます。p1

このようなコードでは避けることができます。私はリンクリストでforループを使用するのが好きではなく、whileは次のリンクの設定を容易にします。削除p3は、次のp1の惑星であるかもしれないので、全体のコンセプトは、欠陥があるしかし

struct planet *p1link, *p3link; 

p1 = head; 
while(p1 != NULL) { 
    p1link = p1->next;    // collect next link now 
    p3 = p1->next;     // avoid detecting B-A as well as A-B 
    while(p3 != NULL) { 
     p3link = p3->next;   // collect next link now 
     //Collision logic 
     if(p1->mass >= p3->mass){ 
      destroy(remove(p3)); 
     } else { 
      destroy(remove(p1)); 
     } 
     p3 = p3link;    // next 
    } 
    p1 = p1link;     // next 
}  

。だから私は構造体のメンバーpendingを含むことをお勧めし、その後、死んだ惑星を取り除くためにリストの別の解析を行います。

+0

私は、次の惑星に移っている間に削除するための効率的な解決策を見つけようとしています。 – Alex

+0

@Alex私は答えを広げました。 –

関連する問題