![]() |
Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Liste der Anhänge anzeigen (Anzahl: 1)
Ich werde aus meinem Problem einfach nicht schlauer. Das Thread vorher war nicht das gelbe vom Ei, daher hab ich ihn löschen lassen. Ich bin jetzt gerade auf der Suche nach dem eigentlichen Problem und das hat mit der Funktion System.Copy(), auf ein Array angewendet zu tun. Hier mal der Code, um welches es sich dreht:
Delphi-Quellcode:
Die untere Variante wollte ich eigentlich nutzen, da ich denke, dass diese effizienter funktioniert, als das was ich da mache, also als Variante (1). Nun, warum habe ich Variante (1) überhaupt geschrieben und kann (2) nicht nutzen: Wenn ich den Code compiliere und dann ausführe, bekomme ich, wenn ich Variante (2) nutze, eine AccessViolation wenn System.Copy() ausgeführt wird -- allerdings nur unter bestimmten Voraussetzung, aber dazu später mehr:
TApDynamicArray<T> = record
private const {...} private type {...} private {...} public {...} function Clone(const StartIndex, Count: Integer): TArray<T>; {...} end; function TApDynamicArray<T>.Clone(const StartIndex, Count: Integer): TArray<T>; var NewArray : TArray<T>; i : Integer; begin // (1) System.SetLength(NewArray, Self.Length); for i := 0 to Self.Length - 1 do NewArray[i] := FData[i]; Result := NewArray; // ------------------------------------------------ // (2) // Result := System.Copy(FData, StartIndex, Count); end;
Code:
Es drängt sich mir hier die Frage auf, was zum Teufel denn da schief laufen kann? Wo kann es beim Befehl System.Copy() krachen? Habe in der Doku nichts gefunden, ebenso wenig im Netz.
Im Projekt Project1.exe ist eine Exception der Klasse EAccessViolation mit der Meldung 'Zugriffsverletzung bei Adresse 00408278 in Modul 'Project1.exe'. Lesen von Adresse F8C483ED' aufgetreten.
Nun zu der "tollen" Voraussetzung, denn jetzt wird es ganz lustig: unter public habe ich im Moment gefühlt 70-80 Methoden definiert, später werden es noch ein paar mehr werden. Habe auch ein paar Operatoren überladen und eine Klassenmethode ist vorhanden. Diese Clone-Methode mit dem System.Copy()-Aufruf ist im Moment an Stelle 7 der Methodendeklarationen, die Klassenmethoden bzw. Operatoren mitgerechnet, d.h. ohne diese wäre die Clone-Methode an Stelle 1. Verschiebe ich die Clone-Methode an Stelle 45(!) oder weiter nach unten, dann kann ich den System.Copy()-Aufruf nutzen und auf meinen eigenen Code verzichten. Ist diese also zwischen Position 1 und 45 platziert, erhalte ich oben genannte Exception. Und jetzt erzählt mir mal warum das so ist :stupid: Ich persönlich glaube, dass der Delphi-Compiler hier ein Problem mit was weiß ich auch immer hat und einfach Käse produziert... Aber ich lasse mich echt liebend gerne überaschen... Anbei findet ihr die Demo, bei der es so toll kracht :roll: |
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Solange beide Arrays konsistente Daten enthalten, genug Speicher zur Verfügung steht und die RTTI-Infos korrekt sind,
sollte beim Copy eigentlich nichts knallen. Genug RAM ist wohl OK, da sonst ja ein OutOfMemory erscheinen würde. Die Daten in den Arrays sind konsistent? Aber in Verbindung mit der RTTI vermute ich jetzt einfach mal, daß Die Generics da irgendwo Mist bauen (wie immer), denn daraus werden ja die Informationen über den Aufbau der Daten geholt und damit auch über die Methode des Kopierens, bzw. die Speicherverwaltung. Du kannst also nut den Fehler im QC melden, hoffen das die sich mal auskäsen, bzw. überhaupt mal reagieren und danach dann die entpsrechenden Bugfixes (XE2 oder XE3) kaufen. Oder du bleibst bei deiner funktionierenden Variante. |
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Du kannst ja mal versuchen, die Funktion _DynArrayCopyRange der System.pas Schritt für Schritt durchzugehen ...
|
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Jo, die Daten sind konsistent und eigentlich passt alles. Via Debugger kann ich das Array wunderbar einsehen und alle Daten auslesen. Also von dem her sollte alles passen.
Ich find ja meinen "Zusatz" recht krass... Kopiere ich die Methode weiter runter klappt alles. Wie kann sowas sein? Für das QC ist mein Projekt im Moment etwas zu groß, müsste es daher erst noch etwas kleiner machen und den Fehler genauer eingrenzen. Zitat:
Habe es jetzt mal so gebaut, in der Hoffnung, dass es bei großen Arrays schneller ist als mein obiger Code:
Delphi-Quellcode:
Melde mich dann wieder, wenn ich was nähere von der _DynArrayCopyRange() Methode weiß.
function TApDynamicArray<T>.Clone(const StartIndex, Count: Integer): TArray<T>;
begin System.SetLength(Result, Self.Length); if (Self.Length > 0) then Move(FData[0], Result[0], Self.Length); end; |
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Zitat:
(Von einem C-Compiler für Mikrocontroller bin ich es gewöhnt, dass der oft scheiße baut. Z.B. wenn man eine Variable hinzufügt. Fügt man noch eine hinzu, dann geht es wieder.) |
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Ist deine Instanz von TApDynamicArray vielleicht gar nicht initialisiert?
|
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Zitat:
Zitat:
Habe mir jetzt auch mal die _DynArrayCopyRange angeschaut und siehe da, himitsu hatte recht. Zitat:
Zitat:
Delphi-Quellcode:
var
A : TApDynamicArray<Integer>; begin try // Some basics TTest.Print(A); // -> [] SetLength(Tmp, 2); A := Tmp; TTest.Print(A); // -> [0;0] TTest.SetUnsortedData(A); // -> Setzt die Länge auf 10 und füllt das Array TTest.Sort(A); // <- in der Method wird Clone aufgerufen -> Exception |
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Records haben keine Instanzen.
Gut, es kommt jetzt noch darauf an, welche Typen er innerhalb seines Records verwendet, aber Vieles wird ja von Delphi automatisch initialisiert. Vorallem dann, wenn Dieses für eine korrekte (automatisch) Speicherverwaltung nötig ist. Für normale dynamische arrays gibt es aber auch shcon eine Clone-Funktion ... die nennt sich Copy :stipid:
Delphi-Quellcode:
MeinKlon := Copy(DasOriginalArray);
Delphi-Quellcode:
(normale dynamische arrays haben zwar eine Referenzzählung, aber keine prüfung, beim Schreibzugriff :wall: )
var a, b, c: array of Integer;
SetLength(a, 1); a[0] := 123456789; b    := a; b[0] := 666; c    := Copy(a); c[0] := 987654321; ShowMessage(Format('%d %d %d', [a[0], b[0], c[0]])); // 666 666 987654321 Genauso, wie man neuerdings den letzen Parameter weglassen kann, kann man schon sehr lange alle Index-Parameter weglassen. |
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
oh, da hatte ich zu flüchtig hingeschaut. Hab das "record" bei der Declaration übersehen.
|
AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Hm... Ich würde behaupten Delphi verschlampt die TypInfos irgendwo. Denn die System.Copy() läuft direkt in die _DynArrayCopyRange() rein und darin wird dann die Exception geworfen, d.h. die TypInfos fehlen imho von vorn herein. Dann muss ich wohl mit meinem Workaround leben, obwohl mich sowas ungemein nerv... :roll: Aber sonst hätten die Embarcadero-Mitarbeiter ja nichts mehr zu fixen.
@himitsu: Kennst du mehr solcher Probleme, dass TypInfos bei der Verwendung von Generics fehlen? Scheinst da ja recht gut auf dem Laufenden zu sein. Habe dieses nette Feature noch nicht so lange in Gebrauch. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:33 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz