Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Verständnisproblem zur Größenangabe von Array
Bruce - So 04.01.04 20:40
Titel: Verständnisproblem zur Größenangabe von Array
Hallo!
Es funktioniert zwar, aber ich verstehe nicht warum :o :
In meinem Programm kann der Anwender Buttons per Drag and Drop auf eine Grafik ziehen. Die Buttons werden dynamisch per Array erstellt.
Da ich noch mit Delphi3 arbeite und das keine dynamischen Arrays kennt, muss ich ein statisches benutzen.
Delphi-Quelltext
1:
| BZiel : ARRAY[1..10] OF TFlatButton; |
Wenn ich das Array so deklariere, dann sollte da doch "Platz" sein für 10 Buttons, oder?
Ich kann aber ohne Probleme mehr als 10 Buttons erstellen zur Laufzeit. Ich hatte erwartet das irgendeine Fehlermeldung kommt, weil das Array "überläuft". Da nichts passiert meine Frage: Welchen Sinn hat denn dann die Angabe überhaupt und was kann passieren wenn die überschritten wird?
Gausi - So 04.01.04 21:13
Kann sein, dass ich mich hier um Kopf und Kragen rede, aber vielleicht folgendes:
Die Array-Deklaration reserviert im Speicher ausreichend Platz für die Daten der 10 Buttons, z.b. 5Bytes pro Button (keine Ahnung, wieviele es sind). Vereinfacht steht dann Button1 an der Speicheradresse 1 bis 5, der zweite dann an 6-10, der letzte dann an 46-50. Der elfte wird dann einfach an die Adresse 51-55 geschrieben. Es kann aber passieren, dass da schon andre Daten drin stehen. Die werden dann überschrieben und sind weg.
Hoffe, das ist soweit richtig. Bitte korrigiert mich, wenn ich hier totalen Müll geschrieben habe ;-)
umpani - So 04.01.04 21:28
Um die Frage zu beantworten müßtest du den Code posten, mit dem du die Buttons zur Laufzeit erstellst.
Gruß Umpani
Bruce - So 04.01.04 22:29
Hast recht :) So erstell ich die:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32:
| procedure TForm1.ZieleMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin BZieleControl := BZieleControl+1; BZieleNr := BZieleControl; GetCursorPos(mouseposition); mouseposition := Form1.ScreenToClient(mouseposition); If (Mouseposition.x > 630) OR (Mouseposition.y < 64) then begin BzieleControl := BZieleControl -1; exit; end else BZiel[BZieleNr] := TFlatButton.Create(Form1); BZiel[BZieleNr].Parent := Form1; BZiel[BZieleNr].Tag := BZieleNr; BZiel[BZieleNr].Left := mouseposition.x-12; BZiel[BZieleNr].Top := mouseposition.y-12; BZiel[BZieleNr].Color := clred; BZiel[BZieleNr].ColorBorder := $FFFFFFFF; BZiel[BZieleNr].ColorDown := clred; BZiel[BZieleNr].ColorFocused := clred; BZiel[BZieleNr].ColorHighLight := $FFFFFFFF; BZiel[BZieleNr].ColorShadow := $FFFFFFFF; BZiel[BZieleNr].OnMouseDown := ZielPunktMouseDown; BZiel[BZieleNr].OnMouseMove := ZielPunktMouseMove; BZiel[BZieleNr].OnMouseUp := ZielPunktMouseUp; Ziele.Color := clred; Ziele.ColorDown := clred; Ziele.ColorFocused := clred; Form5.Show; end; |
jaenicke - Mi 07.01.04 14:41
Titel: ???
Hallo!
Also ich hab Deinen Code ausprobiert! Bei mir KOMMT da eine Fehlermeldung. Ich nehme mal an, dass bei Dir BZieleNr gar nicht über 10 kommt, weil BZieleControl zwischenzeitlich wieder verringert wird.
Setz mal an die Stelle des Aufrufs des Kontruktors (BZiel[BZieleNr] := TFlatButton.Create(Form1)) einen Haltepunkt und sieh mal nach, welchen Wert BZieleNr hat.
Du kannst ohne Probleme an die selbe Position des arrays mehrmals einen neuen Button erzeugen, auf den alten kannst Du dann nur nicht mehr zugreifen.
Ach so: Du könntest auch einfach mal alle Buttons im array einfärben, dann wirst Du vermutlich nicht alle erreichen, und es wird in Deiner Schleife zum Einfärben dann bei einem Wert über 10 ein Fehler kommen.
Wenn bei dem Haltepunkt bei Dir tatsächlich Werte über 10 auftauchen, vergiss alles, was ich bisher gesagt habe. :wink:
Ach so: Mit Delphi 3 hab ich das allerdings nicht probiert...
MfG,
S.J.
Bruce - Mi 07.01.04 16:31
Hi jaenicke!
Seltsam, ich krieg keinen Fehler beim Erstellen der Buttons. Ich kann ohne Probleme 15 Buttons erstellen und auch jeden einzeln ansprechen und verschieben.
Hab eben mal in dem Formular das nach dem Erzeugen aufgerufen wird den Wert von BZieleNr anzeigen lassen. BZieleNr hatte dann auch die Werte 11, 12...15. Muss auch so sein, denn BZieleControl wird nur verringert, wenn man die Maustaste ausserhalb des gewünschten Bereichs
losläßt, aber dann wird ja auch kein Button erzeugt.
Da ich die Positionen in einer Datei abspeichere, stürzt allerdings beim Wiedereinlesen der Daten das Programm ab. Da funktioniert das wohl mit der Arraygröße.
Inzwischen frage ich vor dem Erstellen den Wert von BZieleControl ab und breche ab wenn > 10. Damit bin ich dann auf der sicheren Seite. Aber verstehen würd ichs schon gern.
Gruß, Bruce
Brueggendiek - Mi 07.01.04 23:57
Hallo Bruce!
Normalerweise prüft Delphi die Arraygrenzen nicht. Damit kannst Du bei einem Array von 1 bis 10 auch auf das 256. Element zugreifen. Da liegen aber dann andere Variablen und der Schreibzugriff verursacht Probleme, die dann schwer zu finden sind: "warum verändert sich der Wert einer Variablen von selber?"
Es gibt aber eine Option, die Indexprüfung einzuschalten. Dann gibbet keinen Zugriff mehr, sondern 'ne Exeption. Das ist normalerweise ausgeschaltet, weil das Prüfen der Indizes relativ viel Code erzeugt und man bei sauberer Programmierung die fehlerhaften Zugriffe vermeidet (in der Suchschleife eben nicht nur den Suchbegriff, sondern auf Arraygrenzen prüfen - falls nichts gefunden wird).
Gruß
Dietmar Brüggendiek
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!