2017-10-01 1 views
2

Der folgende Code einen Absturz in meinem Programm verursacht, weilWarum optimiert g ++ einen kritischen Abschnitt des folgenden Codes?

void fractalizeSegment() { 
     // Assume next != NULL 
     double deltaX = next->x - x; 
     double deltaY = next->y - y; 

     // Add 3 new points labeled a1, a2, a3 from this to next 
     Point a3(x + 2.0*deltaX/3.0, y + 2.0*deltaY/3.0, next); 
     double sqr3 = std::sqrt(3.0); 
     Point a2(x + deltaX/2.0 - sqr3*deltaY/2.0, 
      y + deltaY/2.0 + sqr3*deltaX/2.0, 
      &a3); 
     Point a1(x + deltaX/3.0, y + deltaY/3.0, &a2); 

     next = &a1; 
    } 

irgendwie

optimiert
void fractalizeSegment() { 
    next = &a1; 
} 

Verfahren auf p0 aufgerufen = {x = 0, y = 0, next = 0x7fffffffe100 }, die auf p1 = {x = 1, y = 0, next = 0x0} zeigen.

Durch das Programm im Debugger Analyse fand ich, dass, wenn ich in der Methode fractalizeSegment bin:

a1 = {x = 6.9533558075099091e-310, y = 6.9533558075098597e-310, next = 0x7fffffffe190} 

In Adresse a1.next gibt es

a2 = {x = 6.9533558074508189e-310, y = 4.9406564584124654e-324, next = 0x34}. 

Ehrerbietung Versuch (* a2 .next) .next verursacht einen Segmentierungsfehler.

Warum optimiert g ++ meinen Code so? Wie kann ich das verhindern?

Die aktuelle Problemumgehung, die ich fand, druckte die Werte von a1, a2 und a3, dies verhinderte die Optimierung.

+2

Vielleicht nimmt es * nicht * an, dass 'next! = NULL'? GCC nutzt sehr aggressiv undefiniertes Verhalten bei der Optimierung von Code wie diesem. –

+1

'next = &a1;' wird sofort baumeln. –

+0

Das Hinzufügen eines if (next! = NULL) um den Code ändert nicht das Verhalten – Sven

Antwort

7

a1 ist eine lokale automatische Variable, die bei der Rückkehr von der Funktion zerstört wird, so dass jede Verwendung von *next danach undefiniert ist. Der Compiler denkt, dass Sie diese Werte sicherlich nicht verwenden werden, also warum sollten Sie sie berechnen?

Sie wollen wahrscheinlich a1 in der Halde erstellen:

next = new Point(x + deltaX/3.0, y + deltaY/3.0, &a2); //no need of a1. 

Vielleicht auch a2 und a3 sollten dynamisch zugewiesen werden, aber das hängt von der Implementierung von Point, dass man nicht zeigen.

Und erinnern Sie sich an die zugewiesenen Objekte irgendwo.

+0

"im Heap"? Sicherlich "auf dem Haufen". – tambre

+2

Sie sind wirklich auf "in" vs "auf" plappern? Letzteres ist viel idiomatischer als das erstere, was viel genauer ist. –

+0

@tambre: Nun, ich bin kein Muttersprachler, und ich habe Schwierigkeiten mit _in_ vs _on _... Eine schnelle Suche auf Google zeigt, dass _on_ etwa doppelt mehr als _in_ in diesem Kontext verwendet wird (in diesem Zusammenhang?) , aber beide werden regelmäßig verwendet. Trotzdem denke ich, dass die Bedeutung sowieso klar ist. – rodrigo

Verwandte Themen