2010-12-03 5 views
4

Ich habe dynamische Array in Struct und eine Methode, die das dynamische Array verwendet. Das Problem ist, dass ich einen Bereichsverletzungsfehler erhalte, wenn ich das Programm ausführe. Wenn ich jedoch ein neues dynamisches Array innerhalb der Methode erstelle, funktioniert es gut. Der folgende Code verursacht ein Problem.Fehler: Bereichsverletzung in D-Programmierung

struct MyStr { 
int[] frontArr; 

    this(int max = 10) { 
     frontArr = new int[10]; 
    } 

    void push(int x) { 
     frontArr[0] = x; 
    } 
} 

void main() { 
    MyStr s; 
    s.push(5); 
} 

aber diese funktioniert;

struct MyStr { 
int[] frontArr; 

    this(int max = 10) { 
     frontArr = new int[10]; 
    } 

    void push(int x) { 
     frontArr = new int[10]; // <---Add this line 
     frontArr[0] = x; 
    } 
} 

void main() { 
    MyStr s; 
    s.push(5); 
} 

füge ich im Grunde, dass die Linie, den Umfang zu testen. Es scheint so, als ob der initialisierte FrontArr nicht in der push (int x) -Methode gesehen werden kann. Irgendeine Erklärung?

Vielen Dank im Voraus.

+0

Welche Art von Problem haben Sie? – stonemetal

+0

Haben Sie versucht, einen Writefln-Aufruf in den Konstruktor zu stellen, um sicherzustellen, dass er tatsächlich ausgeführt wird? –

+0

@DK Das ist eine gute Idee. Ja, der erstellte Konstruktor wird nie aufgerufen. – Nate

Antwort

6

Die Initialisierung von Strukturen muss gewährleistet sein. Das heißt, Sie möchten nicht, dass die Standardkonstruktion einer Struktur eine Ausnahme auslöst. Aus diesem Grund unterstützt D keine Standardkonstruktoren in Strukturen. Stellen Sie sich vor,

MyStr s; 

führte zu einer Ausnahme ausgelöst wird. Stattdessen stellt D einen eigenen Standardkonstruktor zur Verfügung, der alle Felder zur Eigenschaft init initialisiert. In Ihrem Fall rufen Sie Ihren Konstruktor nicht auf und verwenden nur die bereitgestellten Standardwerte, was bedeutet, dass frontArr niemals initialisiert wird. Sie wollen so etwas wie:

void main() { 
    MyStr s = MyStr(10); 
    s.push(5); 
} 

Es sollte wohl ein Compiler-Fehler sein, um Standardwerte für alle Parameter eines struct Konstruktor zu haben. Bugzilla

+0

Das klingt richtig. Lass es mich versuchen, und ich werde es dich wissen lassen. Vielen Dank! – Nate

+0

Es funktioniert, super! – Nate

0

Ich könnte mich irren (Ich habe D eine Weile nicht verwendet, so dass es ein wenig eingerostet ist.) Aber FrontArr ist ein Array und in Ihrem Codebeispiel versuchen Sie einen Zeiger auf ein Array zuweisen. Dynamische Arrays arbeiten wie so (Anmerkung kopiert ein D-Tutorial here gefunden)

int[] MyArray; 
MyArray.length = 3; 
+0

Eigentlich (New Int [10]) erzeugt ein Array, kein Zeiger auf ein Array. Wenn dies der Fall wäre, würde der Code überhaupt nicht kompilieren. Der Code sieht gut aus; Ich kann mir nur vorstellen, dass der Konstrukteur nicht aus irgendeinem seltsamen Grund aufgerufen wird. –

+0

Danke, @DK Sieht so aus, als ob mein Wissen über D rostiger ist, als ich dachte. – stonemetal

0

Aus welchem ​​Grund auch immer, nicht D nicht struct Konstrukteure unterstützen, die keine Argumente benötigen, verwenden Sie entweder opCall oder entfernen Sie die Standard initializer auf this()

struct MyStr { 
    int[] frontArr; 

    static MyStr opCall() { 
     MyStr s; 
     s.frontArr = new int[10]; 
     return s; 
    } 

    void push(int x) { 
     frontArr[0] = x; 
    } 
} 
+0

Es hat damit zu tun, dass die 'init'-Eigenschaft aller Typen zur Kompilierzeit bekannt sein muss. Für Strukturen wäre dies der Standardkonstruktor. Aber da ein Konstruktor zur Laufzeit ausgeführt wird, funktioniert das nicht. Also werden die Werte, auf die die Membervariablen direkt initialisiert werden, für 'init' verwendet, und Standardkonstruktoren sind nicht erlaubt. Ein statisches 'opCall()' ist eine Möglichkeit, das Problem zu umgehen. Allerdings müssten Sie etwas wie "auto s = MyStr()" anstatt der "MyStr s", die im Code in der Frage verwendet wird, tun. 'MyStr s' verwendet immer die 'init'-Eigenschaft. –