2012-04-14 10 views
2

Ich entschied mich schließlich, std.RedBlackTree anstelle der integrierten assoziativen Arrays (oder Hash) zu verwenden, weil ich ein sortiertes assoziatives Array benötigt. Das gewünschte Verhalten ähnelt sehr ähnlich std::map in C++/STL.Warum std.RedBlackTree als Karte bricht?

void main() { 

    alias Tuple!(float, float) Pair; 
    alias RedBlackTree!Pair Map; 
    Map m1; 
    m1.insert(Pair(1.1, 2.2)); 
} 

Der obige Code, je nachdem wie man es kompilieren (mit oder ohne -release), werden Segmentierungsfehler verursachen oder Behauptung werfen.

Die gleiche Sache mit diesem:

void main() { 

    struct Pair { float first, second; } 
    alias RedBlackTree!(Pair, "a.first < b.first") Map; 
    Map m1; 
    m1.insert(Pair(1.1, 2.2)); 
} 

Riecht wie ein Bug, aber gibt es eine Abhilfe?

Antwort

8

RedBlackTree ist eine Klasse und muss daher initialisiert werden. m1 ist standardmäßig null. Was Sie sehen, entspricht einer NullPointerException in Java.

Versuchen Sie folgendes:

import std.stdio, std.container; 
void main() { 
    struct Pair { float first, second; } 
    alias RedBlackTree!(Pair, "a.first < b.second") Map; 
    Map m1 = new Map; 
    m1.insert(Pair(1.1, 2.2)); 
} 

Auch als beiseite Tipp für dieses Programmierbeispiel: Sie möchten vielleicht RedBlackTree!(Pair, "a.first < b.first") stattdessen betrachten. Der Grund ist, dass es ein seltsames (nicht ganz undefiniertes, aber wahrscheinlich nicht das, was Sie wollen) Verhalten haben.

Zum Beispiel wäre Pair(1, 2) < Pair(1, 3) wahr. Seltsamerweise wäre Pair(1, 3) < Pair(1, 2) auch wahr.

+0

Ich hatte den Eindruck, dass 'RedBlackTree' eine Struktur war, weil' Array' eine Struktur ist, lol. Auch "a.first Arlen

+0

Als Randnotiz sollte DMD so etwas wie einen Fehler kennzeichnen. Ich meine, es gibt keine Möglichkeit zu sagen, ob ein Typ eine Klasse ist oder nicht, ohne den Quellcode oder die Dokumente, oder? – Arlen

+0

Nicht, dass ich davon weiß. Im Allgemeinen benutze ich die Dokumente, während ich code, wenn ich nicht vertraut bin mit dem, was ich arbeite ... aber die "AssertError ... null this" (wenn ich nicht kompilieren mit dem Release-Flag) ist normalerweise die Art, wie ich herausfand, dass ich eine Klasse für eine Struktur verwechselte. –

3

Ich möchte darauf hinweisen, dass die ersten beiden Dinge, nach denen Sie im Allgemeinen suchen sollten, wenn Sie einen segfault erhalten, sind NULL-Zeiger/Referenzen und unendliche Rekursion. Und Sie können einen Debugger verwenden, um genau zu bestimmen, wo sie auftreten.

RedBlackTree ist eine Klasse und daher jede Variable, die ein RedBlackTree ist ein Referenztyp ist. Sie müssen ihm also einen anderen Wert als null zuweisen oder null, und Sie erhalten einen segfault, wenn Sie ihn verwenden. Das Gleiche passiert auch, wenn Sie eine Variable haben, die ein Zeiger auf etwas ist, und Sie haben versucht, sie zu verwenden, ohne ihr einen Wert ungleich null zuzuweisen.

Ihre Initialisierung Linie sollte

Map m1 = new Map; 

Alternativ sein, mit RedBlackTree, könnten Sie tun

Map m1 = redBlackTree!"a.first < b.first"(Pair(1.1, 2.2)); 

redBlackTree ist eine Hilfsfunktion für die Erstellung und Elemente in eine RedBlackTree in einer Zeile eingefügt wird.