2017-01-06 2 views
0

Ich erstelle eine Planetensimulation, die eine doppelt verknüpfte Liste und mehrere Schleifen verwendet, um Kräfte, Kollisionen usw. zu berechnen. Das Problem, das ich habe, ist ein Lesezugriffsverletzungsfehler beim Versuch, einen Planeten aufgrund einer Kollision zu löschen.Lesezugriffsverletzung beim Durchlaufen der LinkedList

Bei der Suche nach einer Kollision wird der kleinere der beiden Planeten gelöscht, und die Art, wie ich ihn geschrieben habe, ist, dass der kleinere Planet in der Gleichung aus der umfassenden Schleife stammen kann, die, wenn gelöscht, die Schleife durchbricht.

Eine Kombination aus neu zu C; seit Tagen auf dasselbe Thema starren; und dass mein Dozent für die Klasse uns dazu bringt, einen C/C++ - Hybrid zu verwenden, führt dazu, dass ich mit Schwierigkeiten daran denke, einen effizienten Weg zu finden, das Problem zu lösen. Das Verschieben der Loops kann und hat das Problem gelöst, hat aber eine drastische Auswirkung auf die Performance der Simulation.

Der Code kann unten gesehen werden:

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 
        } 
       } 
      } 
    } 

Was ich suche ist einige Ratschläge, wie p1 effizient zu löschen und ohne Unterbrechung der Schleife.

Jede Hilfe wird sehr geschätzt, und bitte verzeihen Sie meinen weniger als sauberen Code.

+2

Ihr Dozent unterrichtet C, mit Ausnahme von 'new' und' delete'. Pfui. – Zeta

+1

Abgesehen von der schrecklich komischen Kombination, warum hat 'destroy' einen Rückgabewert? Alles, was es zurück gibt, ist sowieso 0, könnte auch keine Rendite haben? – UnholySheep

+0

Korrekt, aber aus irgendeinem Grund kehrt er zurück zu "malloc" für Texturen ... – Alex

Antwort

2

Ausbrechen der inneren Schleife, wenn p1 zerstört ist, wird nicht die äußere Schleife, wo p1 von der Schleifensteuerung dereferenziert wird, nachdem es gelöscht wurde.

Sie können es mit Code vielleicht so vermeiden. Ich mag es nicht, for Loops mit einer verknüpften Liste zu verwenden, und die while macht es einfach, den nächsten Link einzurichten.

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 
}  

jedoch das gesamte Konzept fehlerhaft, weil die p3 Du löschen könnte die nächsten p1 Planeten sein. Daher schlage ich vor, ein Strukturelement pending einzuschließen und anschließend eine weitere Analyse der Liste durchzuführen, um tote Planeten zu entfernen.

+0

Ich bin mir bewusst, dass ich versuche, eine effiziente Lösung für das Löschen zu finden, während ich immer noch zum nächsten Planeten gehe. – Alex

+0

@Alex Ich habe die Antwort erweitert. –

Verwandte Themen