Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Grenzunterschreitung bei Array[1...9] ohne Exception (https://www.delphipraxis.net/208270-grenzunterschreitung-bei-array%5B1-9%5D-ohne-exception.html)

cs.rumpelstilzchen 6. Jul 2021 14:42

Delphi-Version: XE4

Grenzunterschreitung bei Array[1...9] ohne Exception
 
Hallo Leute :hi:

Habe grad bemerkt, dass folgender Code zur Laufzeit KEINE Exception auslöst...

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  aTest : Array[1..9] of Integer;
  iIdx : Integer;
begin
  iIdx := 0;
  aTest[iIdx] := 123;
end;
Wo landet denn der zugewiesene Wert??? :?

Erst wenn ich danach lesend auf das Element zugreife, knallts:

Delphi-Quellcode:
  Label1.Caption := IntToStr(aTest[iIdx]);

Klaus01 6. Jul 2021 14:57

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
.. ist bei Dir range Checking - bzw. Bereichsüberprüfung in den Compliler Optionen gesetzt?

Grüße
Klaus

Uwe Raabe 6. Jul 2021 14:57

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
Zitat:

Zitat von cs.rumpelstilzchen (Beitrag 1491953)
Habe grad bemerkt, dass folgender Code zur Laufzeit KEINE Exception auslöst...

Vermutlich, weil du das Range-Checking nicht eingeschaltet hast.

Zitat:

Zitat von cs.rumpelstilzchen (Beitrag 1491953)
Wo landet denn der zugewiesene Wert??? :?

Damit überschreibst du den Speicherbereich vor dem Array.

Zitat:

Zitat von cs.rumpelstilzchen (Beitrag 1491953)
Erst wenn ich danach lesend auf das Element zugreife, knallts:

Verwundert nach der vorigen Antwort aber auch nicht wirklich.

Papaschlumpf73 6. Jul 2021 15:28

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
Mir ist das erst neulich aufgefallen. Auf ein String-Array 1..9 konnte ich plötzlich mit Index 0 lesend zugreifen. Es kam ein großes "A" als Ergebnis. Keine Ahnung. Der try except - Block außenrum, der in diesem Falle früher "unbekannt" ausgegeben hatte, ist nicht angesprungen.

jaenicke 6. Jul 2021 22:05

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
Hintergrund ist, dass die Prüfung, ob die Arraygrenzen eingehalten werden, logischerweise Zeit kostet. Deshalb muss man die bereits genannte Bereichsprüfung explizit aktivieren.

QuickAndDirty 6. Jul 2021 22:13

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
Delphi-Quellcode:
{$R+}
procedure TForm1.Button1Click(Sender: TObject);
var
  aTest : Array[1..9] of Integer;
  iIdx : Integer;
begin
  iIdx := 0;
  aTest[iIdx] := 123;
  Label1.Caption := IntToStr(aTest[iIdx]);
end;
und jetzt?

Papaschlumpf73 6. Jul 2021 22:48

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1491974)
Delphi-Quellcode:
{$R+}
procedure TForm1.Button1Click(Sender: TObject);
var
  aTest : Array[1..9] of Integer;
  iIdx : Integer;
begin
  iIdx := 0;
  aTest[iIdx] := 123;
  Label1.Caption := IntToStr(aTest[iIdx]);
end;
und jetzt?

Drück mal auf Projekt > ...neu erzeugen. Dann sollte es klappen. Einfach F9 hat bei mir nicht gereicht. ????

Papaschlumpf73 6. Jul 2021 22:52

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
Wenn ich in den Projektoptionen unter Erzeugen > Delphi-Compiler > Compilieren > Laufzeitfehler die "Bereichsüberprüfung" aktiviere, dann wird auch wieder eine Exception zur Laufzeit geworfen (nachdem ich das Projekt neu erzeugt habe; F9 reicht nicht). Die Option ist jetzt fett, d.h. es ist nicht der Standardwert. Ich frage mich jetzt, wer das wann verändert hat. Ich habe hier niemals an den Einstellungen rumgespielt und früher wurde die Exception definitiv geworfen.

Andersherum muss ebenfalls das Projekt neu erzeugt werden, wenn man die Option wieder deaktiviert; auch hier reicht F9 nicht aus.

jaenicke 7. Jul 2021 13:53

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
Zitat:

Zitat von Papaschlumpf73 (Beitrag 1491978)
Andersherum muss ebenfalls das Projekt neu erzeugt werden, wenn man die Option wieder deaktiviert; auch hier reicht F9 nicht aus.

Das ist klar. Denn Units werden nur neu kompiliert, wenn sie sich geändert haben. Das ist hier ja nicht der Fall.

Schöner wäre natürlich, wenn der Compiler auch die Änderung von Projekteinstellungen berücksichtigen würde, aber ob entsprechende Einstellungen geändert wurden, kann er schlicht nicht erkennen, da es dafür keine Markierung gibt.

QuickAndDirty 25. Jul 2021 12:17

AW: Grenzunterschreitung bei Array[1...9] ohne Exception
 
Zitat:

Zitat von Papaschlumpf73 (Beitrag 1491977)
Zitat:

Zitat von QuickAndDirty (Beitrag 1491974)
Delphi-Quellcode:
{$R+}
procedure TForm1.Button1Click(Sender: TObject);
var
  aTest : Array[1..9] of Integer;
  iIdx : Integer;
begin
  iIdx := 0;
  aTest[iIdx] := 123;
  Label1.Caption := IntToStr(aTest[iIdx]);
end;
und jetzt?

Drück mal auf Projekt > ...neu erzeugen. Dann sollte es klappen. Einfach F9 hat bei mir nicht gereicht. ????

Du musst das Project "erzeugen". Leider ist F9 mehr so eine Zeitsparvariante von "Erzeugen".

Auf jedenfall kann ich nur davon abraten {$R+} oder RANGECHECK ON als Compiler option zu verwenden wenn das Produkt ausgeliefert wird. Es hilft aber manchmal komische Fehler im Testbetrieb zu finden.

[OT]
Wenn du ein recht aktuelles Delphi verwendest(Genereics, Classhelpers) dann kann ich dir noch folgende Unit von Github für Offene Arrays empfehlen.
https://github.com/WilliCommer/ArrayHelper

Die unit heist ArrayHelper.pas aber statt des helpers der inder Unit ist solltest du den TArrayRecord nutzen. Spart einem viel Arbeit und die Syntax sieht dann mehr Objekt orientiert aus...
Delphi-Quellcode:
var
  A: TArrayRecord<string>;
begin
  A.SetValues(['a','b','c']);
  A.Add('d');
  assert(  A.Count = 4 );   // same as length(A.Items);
  assert(  A[1] = 'b' );
  assert(  A.IndexOf('a') = 0 );
  for S in A do
    ..
[/OT]


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz