AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Wann kann System.Copy(Array, Index, Count) eine Exception liefern?
Thema durchsuchen
Ansicht
Themen-Optionen

Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

Ein Thema von s.h.a.r.k · begonnen am 6. Mai 2011 · letzter Beitrag vom 9. Mai 2011
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#1

Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 09:19
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:
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;
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:
Code:
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.
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.

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 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
Angehängte Dateien
Dateityp: rar ApArrayDemo.rar (11,7 KB, 4x aufgerufen)
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.168 Beiträge
 
Delphi 12 Athens
 
#2

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 09:25
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.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 6. Mai 2011 um 09:37 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#3

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 09:30
Du kannst ja mal versuchen, die Funktion _DynArrayCopyRange der System.pas Schritt für Schritt durchzugehen ...
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#4

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 09:40
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.
Du kannst ja mal versuchen, die Funktion _DynArrayCopyRange der System.pas Schritt für Schritt durchzugehen ...
Jo, könnte ich wahrlich mal tun... Aber im Moment ist mir echt nicht danach. Hatte schon ewige Zeiten (>3h) suchen müssen, warum und wo es überhaupt knallt. Hatte echt nicht erwartet, dass es an so einer Methode liegt und daher erst alles andere untersucht. Lustigerweise erschien der Fehler erst, nachdem ich diese Clone-Methode weiter nach oben gesetzt hatte, da ich eine logische Reihenfolge der Methoden aufgebaute. Und nein, ich werde diese Clone-Methode nicht da runter kopieren -- sowas fällt mir gar nicht erst ein

Habe es jetzt mal so gebaut, in der Hoffnung, dass es bei großen Arrays schneller ist als mein obiger Code:
Delphi-Quellcode:
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;
Melde mich dann wieder, wenn ich was nähere von der _DynArrayCopyRange() Methode weiß.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

Registriert seit: 17. Jan 2007
907 Beiträge
 
Delphi XE2 Professional
 
#5

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 09:44
Habe es jetzt mal so gebaut, in der Hoffnung, dass es bei großen Arrays schneller ist als mein obiger Code: [...]
Da werden die Parameter StartIndex und Count aber nicht ausgewertet


(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.)
Chris
Die Erfahrung ist ein strenger Schulmeister: Sie prüft uns, bevor sie uns lehrt.
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#6

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 09:51
Ist deine Instanz von TApDynamicArray vielleicht gar nicht initialisiert?
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#7

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 09:57
Habe es jetzt mal so gebaut, in der Hoffnung, dass es bei großen Arrays schneller ist als mein obiger Code: [...]
Da werden die Parameter StartIndex und Count aber nicht ausgewertet
Jo, schon gemerkt gehabt -- muss wohl am dem fehlenden Schlaf liegen. Man sollte einfach nicht die komplette nach durchcoden Trotzdem danke für den Hinweis!

(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.)
Ist ja wie russisches Roulette So schön Optimierungen des Compilers auch sein mögen, es sollte aber doch möglichst funktionieren... Dann kann es ruhig einen kleinen Tick langsamer sein.

Habe mir jetzt auch mal die _DynArrayCopyRange angeschaut und siehe da, himitsu hatte recht.
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.
An der Adresse, auf die zugegriffen wird, sollten eigentlich Typinformationen stehen, allerdings läuft da irgendwas ziemlich schief. Mal schauen, ob es nicht noch eine Rettung für den Spass gibt. Der Umstand der Kombination aus diesem netten Problem und der Position der Methode innerhalb der Methoden-Deklarationen, ist aber echt genial
Ist deine Instanz von TApDynamicArray vielleicht gar nicht initialisiert?
Ich denke, dass ich nicht mehr als das hier benötige, da es sich um einen record handelt, nicht um eine Klasse:
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
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.168 Beiträge
 
Delphi 12 Athens
 
#8

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 09:58
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:

MeinKlon := Copy(DasOriginalArray);
Delphi-Quellcode:
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
(normale dynamische arrays haben zwar eine Referenzzählung, aber keine prüfung, beim Schreibzugriff )

Genauso, wie man neuerdings den letzen Parameter weglassen kann,
kann man schon sehr lange alle Index-Parameter weglassen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 6. Mai 2011 um 10:19 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von SirThornberry
SirThornberry
(Moderator)

Registriert seit: 23. Sep 2003
Ort: Bockwen
12.235 Beiträge
 
Delphi 2006 Professional
 
#9

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 10:01
oh, da hatte ich zu flüchtig hingeschaut. Hab das "record" bei der Declaration übersehen.
Jens
Mit Source ist es wie mit Kunst - Hauptsache der Künstler versteht's
  Mit Zitat antworten Zitat
Benutzerbild von s.h.a.r.k
s.h.a.r.k

Registriert seit: 26. Mai 2004
3.159 Beiträge
 
#10

AW: Wann kann System.Copy(Array, Index, Count) eine Exception liefern?

  Alt 6. Mai 2011, 10:17
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... 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.
»Remember, the future maintainer is the person you should be writing code for, not the compiler.« (Nick Hodges)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:07 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