2012-04-04 2 views
1

Ich versuche, das 'Last Attribut mit einem 2D-Array in Ada zu verwenden, aber ich kann nicht scheinen, die richtige Syntax dafür zu finden.Wie verwende ich das letzte Attribut für mehrdimensionale Arrays in Ada?

Ich weiß, dass ich, wenn ich ein 1D-Array/Vektor habe, A'last oder A'last (n) verwenden kann, wobei n die n-te Dimension ist. Aber wenn ich die folgenden

type UnconstrainedArray_2D is array (Integer range <>, Integer range <>) of Integer; 

function temp(tempIn : in Integer; 
       Table : in UnconstrainedArray_2D) return Integer is 
tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn); 

begin 
    for i in 0..tempTable'last(1) loop 
     for j in 0..tempTable'last(2) loop 
      tempTable(i, j) := Table(i,j); 
     end loop; 
    end loop; 
end temp; 

erhalte ich die folgenden Kompilierung-Fehler:

Storage_Error stack overflow (or erroneous memory access)

Also, was mache ich falsch?

Ich verwende GNAT Pro 6.4.1 unter Linux.

+0

Ich habe festgestellt, dass der Fehler mit der 'Table: in UnconstrainedArray_2D' in der Funktion zusammenhängt. Aber ich bin mir immer noch nicht sicher, was ich falsch gemacht habe. – Fred

+0

Ich habe auch auf GNAT Pro 7.0.1 aktualisiert, um zu sehen, ob es ein Compiler Bug war, aber ich bekomme den gleichen Fehler. – Fred

+1

Kein gültiger Auszug, ich nehme an "temp_table ist UnconstrainedArray_2D ..." s.b. "temp_table: UnconstrainedArray_2D ...". Das behebt, dass die anderen fehlenden Schlüsseldaten die Argumente sind, die Sie im Aufruf von temp() angeben. Wenn es sich um große Werte handelt, kann das Zuweisen einer lokalen Variablen (tempTable) den Stapel leicht durchbrechen. Es gibt auch spröde Annahmen über Array-Indexbereiche, die erfordern, dass die Argumente tempIn und Table mit der Deklaration der Variable tempTable konsistent sind, z. Es wird angenommen, dass die Tabelle mit 0 Indizes beginnt, wobei tempIn> = ist als die Tabellenindizes. "Last ist nicht dein Problem. –

Antwort

3

Ich wäre sehr überrascht, wenn Sie eine KompilierzeitStorage_Error auf diesen Code bekommen.

Ich habe mir eine Kopie Ihres Codes geschnappt und wie folgt geändert: es kompiliert ohne Fehler GNAT mit (gcc-4.4):

procedure Array_2D is 
    type UnconstrainedArray_2D is array (Integer range <>, Integer range <>) of Integer; 

    function temp(tempIn : in Integer; 
        Table : in UnconstrainedArray_2D) return Integer is 
    tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn); 

    begin 
     for i in 0..tempTable'last(1) loop 
      for j in 0..tempTable'last(2) loop 
       tempTable(i, j) := Table(i,j); 
      end loop; 
     end loop; 
     return 42; -- added this 
    end temp; 
begin 
    null; 
end Array_2D; 

(. Beachten Sie, dass ich die fehlenden return Aussage in temp hinzufügen hatte)

Ihre Syntax für die 'Last Attribut (nicht "command") richtig ist, aber da Ada Arrays beliebige untere und obere Grenzen haben können, ist es besser, anstatt das 'Range Attribut zu verwenden:

for i in tempTable'Range(1) loop 
     for j in tempTable'Range(2) loop 
      tempTable(i, j) := Table(i,j); 
     end loop; 
    end loop; 

Was die Storage_Error Ausnahme, das könnte leicht ha ppen zur Laufzeit (nicht Kompilierzeit) wenn Sie Ihre temp Funktion mit einem sehr großen Wert für tempIn aufrufen. Denken Sie daran, dass es genügend Platz zum Halten von tempIn**2Integer Objekten zuweisen muss. Vermutlich haben Sie auch ein anderes UnconstrainedArray_2D Objekt erstellt, das als Table Parameter übergeben werden soll.

Es ist denkbar, dass der Compiler selbst mit einer Storage_Error Ausnahme sterben könnte, aber ich sehe nichts in Ihrem Code, der das verursachen könnte.

Zeigen Sie uns ein vollständiges (aber kleines) Programm, das das Problem, das Sie haben, zusammen mit der genauen (Kopieren und Einfügen) Fehlermeldung zeigt. Bitte unterscheiden Sie deutlich zwischen Kompilier- und Laufzeitfehlern.

+0

Entschuldigung, dass ich keinen kompilierbaren Code gepostet habe. Ich hatte gedacht, dass mein Fehler syntaktisch war und postete den Code, der die Möglichkeit bieten würde, die falsche Syntax zu identifizieren. Vielen Dank für das Beispiel. Der Fehler, den ich bekomme, ist definitiv zur Kompilierzeit und ich habe festgestellt, dass, wenn ich 'type UnconstrainedArray_2D ändere, Array (Integer Bereich <>, Integer Bereich <>) von Integer ist, um UnconstrainedArray_2D zu array (Integer Bereich 0..Integer 'last, Integer Bereich 0..Integer'last) von Integer; 'dann wird der Storage_Error disapperiert. – Fred

+0

Haben Sie wirklich einen * Kompilierzeit * Fehler bekommen? –

+0

Ja, es heißt 'Compilation aufgegeben'' gnatmake: "file.adb" Kompilierungsfehler' – Fred

2

Ihr tempTable könnte einen Bereich von 0..tempIn haben, aber Sie wissen nicht, welchen Bereich Ihr Table hat. Sie könnten auch unterschiedlich lang sein.

Sie müssten prüfen, ob die Länge gleich ist und dann relativ Indizes verwenden, wie folgt aus:

function temp(tempIn : in Integer; 
       Table : in UnconstrainedArray_2D) return Integer is 
    tempTable : UnconstrainedArray_2D(0..tempIn, 0..tempIn); 

begin 
    if tempTable'Length (1) /= Table'Length (1) or else 
     tempTable'Length (2) /= Table'Length (2) 
    then 
     raise Constraint_Error; -- or something else 
    end if; 
    for i in 0 .. tempTable'Length (1) - 1 loop 
     for j in 0 .. tempTable'Length (2) - 1 loop 
      tempTable(tempTable'First (1) + i, tempTable'First (2) + j) := 
       Table(Table'First (1) + i, Table'First (2) + j); 
     end loop; 
    end loop; 
end temp; 

auf diese Weise sichergestellt ist, dass beide Tabellen gleich lang sind und alle Indizes gelten.

Wenn Ihre tempTable kleiner als Table sein darf, passen Sie die Längenprüfung einfach an > an. Die Indizes wären immer noch gültig.

0

Ich sehe keinen tatsächlichen Wert für tempIn festgelegt. Wenn der Wert für tempIn in der Funktion temp nicht richtig initialisiert oder explizit festgelegt wurde, dann könnte der Wert in tempIn alles sein und wahrscheinlich nicht etwas, was Sie möchten.


Ich dachte an einen Standardwert. (sollte wohl nicht posten wenn ich mich nicht wohl fühle :-)

+0

Warum sollten Sie einen tatsächlichen Wert für 'tempIn' erwarten? Dies ist eine Funktionsdeklaration, kein Funktionsaufruf! –

Verwandte Themen