Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi EAccessViolation bei Änderung von dynamischem Array (https://www.delphipraxis.net/83630-eaccessviolation-bei-aenderung-von-dynamischem-array.html)

little_budda 5. Jan 2007 09:19


EAccessViolation bei Änderung von dynamischem Array
 
Hallo,

ich habe zwei dynamische Arrays deklariert
Delphi-Quellcode:
...
  aMyMainImages : array of Timage;   // Oberer Symbolteil
  aMyBaseImages : array of Timage;   // Unterer Symbolteil
...
Die Länge der Arrays setze ich mit folgendem Code.
Hierbei ist "iAnzAdressen" als Integer deklariert.
Delphi-Quellcode:
     
...  
  setlength (aMyBaseImages, 0);
  setlength (aMyBaseImages, iAnzAdressen); // Zuweisen der Arraygrösse
  setlength (aMyMainImages, 0);
  setlength (aMyMainImages, iAnzAdressen); // Zuweisen der Arraygrösse
...
Klappt zuerst gut.
Wenn ich diesen Programmpunkt dann das zweite mal erreiche erhalte ich eine Exeption.
(EAccessViolation ... Zugriffsverletzung bei Adresse xxx ...)

Ich denke meine Frage ist ähnlich in diesem Thread,
aber die Antworten dort bringen mich nicht weiter.

Wenn ich bei Neuzuweisung der Arraygröße den Speicherbereich verändere,
wie kann ich meinem Zeiger dann sagen er soll bitte auch auf den neuen Bereich verweisen?

Oder kann ich ein dynamisches Array nachdem ich es mit eine Größe versehen
(angelegt) habe wieder löschen und neu anlegen?

Gruß Holger.

:gruebel:

sirius 5. Jan 2007 10:14

Re: EAccessViolation bei Änderung von dynamischem Array
 
Ich glaube, hier stellt sich erstmal die Frage: Was machst du zwischenzeitlich mit deinen arrays?

oki 5. Jan 2007 10:19

Re: EAccessViolation bei Änderung von dynamischem Array
 
Zitat:

Zitat von little_budda
Oder kann ich ein dynamisches Array nachdem ich es mit eine Größe versehen
(angelegt) habe wieder löschen und neu anlegen?

Ja, das kannst du. Eine zuweisung über SetLength reserviert den nötigen Speicher. Jede weitere Zuweisung verkürzt oder verlängert das Array.
aus eigener erfahrung kann ich bestätigen, dass das auch ordentlich klappt. somit muß dein Fehler an einer anderen stelle stecken.

Gruß oki

shmia 5. Jan 2007 10:22

Re: EAccessViolation bei Änderung von dynamischem Array
 
Ich würde statt array of TImage ganz eindeutig zu der Kontainerklasse TComponentList raten.
Das vereinfacht das Handling und erweitert deine Möglichkeiten.
Du solltest wirklich keinen Gedanken an das dynamische Array mehr verschwenden.

Description

Use a TComponentList to store and maintain a list of components. TComponentList provides properties and methods to add, delete, rearrange, locate, access, and sort components. Like TObject List, TComponentList controls the memory of its components; unless the OwnsObjects property is set to False (or the components are removed with the Extract method), TComponentList frees its components when they are removed from the list or when the TComponentList instance is itself destroyed.

In addition, TComponentList tracks its components. Whenever a component is freed, TComponentList automatically updates itself by deleting the reference to the freed component and packing the list.

little_budda 5. Jan 2007 11:10

Re: EAccessViolation bei Änderung von dynamischem Array
 
Hallo,

1.
die Idee mit der Komponentenliste ist klasse.

Ich habe die Liste angelegt und meine esrte Grafik zugewiesen.
Delphi-Quellcode:
...
  myMainImage := timage.Create(frm_main);
  iObjectIndex := aMyMainImages2.Add(myMainImage);
...
Wie komme ich denn jetzt an die Eigenschaften meiner Grafik?
Mit folgendem nicht ...
Delphi-Quellcode:
  aMyMainImages2.items[iObjectIndex].left := 23;
Könnte ich vielleicht ein Beispiel bekommen?


2.
Das Problem mit dem dynamischen Array habe ich auch mit einem TStringArray noch.
Auch hier bekomme ich eine Exeption wenn ich die Länge das zweite mal zuweise.


Gruß Holger.

shmia 5. Jan 2007 11:14

Re: EAccessViolation bei Änderung von dynamischem Array
 
Zitat:

Zitat von little_budda
Wie komme ich denn jetzt an die Eigenschaften meiner Grafik?
Mit folgendem nicht ...
Delphi-Quellcode:
  aMyMainImages2.items[iObjectIndex].left := 23;

Du brauchst den Cast-Operator:
Delphi-Quellcode:
  TImage(aMyMainImages2.items[iObjectIndex]).left := 23;
  // weniger Mutige schreiben
  (aMyMainImages2.items[iObjectIndex] as TImage).left := 23;
Wenn mehrere Aktionen geschehen sollen, dann lohnt sich eine lokale Variable:
Delphi-Quellcode:
var
   actImg : TImage;
begin
   actImg := TImage(aMyMainImages2.items[iObjectIndex]);
   actImg.Left := 23;
   actImg.Top := ...

little_budda 5. Jan 2007 12:07

Re: EAccessViolation bei Änderung von dynamischem Array
 
Hallo,

Die Variante mit der Komponentenliste ist oberklasse. :-)
Ist auch wesentlich schneller als mit dem TImage-Array.

Mein Problem mit dem TStringArray habe ich auch umschifft.
Ich verwende nun einfach eine StringList.
Die reicht für meine Zwecke auch völlig aus.

Danke.

Gruß Holger.

faux 5. Jan 2007 12:19

Re: EAccessViolation bei Änderung von dynamischem Array
 
Zitat:

Zitat von shmia
Wenn mehrere Aktionen geschehen sollen, dann lohnt sich eine lokale Variable...

...oder ein with-Konstrukt:
Delphi-Quellcode:
with aMyMainImages2.items[iObjectIndex] as TImage do
begin
  Left := 23;
  Top := 12;
end;
Soll nicht heißen, dass eine Variante besser ist, sondern nur eine Alternative. ;)

Grüße
Faux


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:39 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