Größe der Weird-Klasseninstanz mithilfe von Klassenmembern, die Arrays generischer Typen sind

8

Unten ist ein sehr einfaches Stück Code, das eine Klassenstruktur in einem Code nachahmt, den ich habe (das Formular enthält nur eine einzige Schaltfläche, die an das click-Ereignis angehängt ist). Ich benutze Delphi XE und XE II und sehe böse Abstürze, wenn ich Objekte in meinem Produktionscode zerstöre, auf denen diese Klasse basiert. Diese Abstürze treten nur auf, wenn ich die Member des Array-Elements in TMyClass in der Clear () -Methode initialisiert habe.

Leider ist der Absturz in diesem Beispielcode bisher nicht wiederholbar, aber er simuliert ein sehr merkwürdiges Verhalten mit Instanzgrößen, von denen ich vermute, dass sie die Ursache des Problems sein könnten.

Wenn ich einen Unterbrechungspunkt in der TMyClass.Clear-Funktion platziere und das InstanceSize-Element der Klassenberichte 1288 ansehe. Das ist seltsam, da die Größe des Array-Elements allein 12kb ist. Ich kann den Typ ändern, der von TRecord2 zu Integer bereitgestellt wird, und ich erhalte das gleiche InstanceSize-Ergebnis. Wenn ich das Array vollständig aus der Klasse entferne, erhalte ich eine Instanzgröße von ~ 264 Byte, was für eine Klasse, die nur eine einzige 128 Byte-Datensatzinstanz enthält, übertrieben erscheint. Dies zeigt an, dass der Compiler 1024 Byte dem Array-Speicher für das Member V (des Typs TT) in TMyClass zugewiesen hat.

Ich bin verdächtig, dass die seltsame Instanzgröße dazu führt, dass schlimme Dinge passieren, wenn ich 12kb Daten in ein Objekt schreibe, von dem der Compiler glaubt, dass es 1kb groß ist.

%Vor%     
Raymond Wilson 28.10.2011, 18:12
quelle

1 Antwort

8

Es ist ein Fehler, wie diese minimale Reproduktion zeigt:

%Vor%

Ausgabe:

%Vor%

Beachten Sie, dass das gleiche Verhalten in Delphi 2010 beobachtet werden kann, der einzigen anderen Delphi-Version, die ich weitergeben muss.

Verfolgen Sie den Debugger unter und finden Sie sich in _GetMem mit dem Size -Parameter gleich 264 , so dass eindeutig nicht genug Speicher zugewiesen wird.

Und nur für den Fall, dass Zweifel bestehen, schlägt diese Version mit einem AV fehl.

%Vor%

Ich habe dies bei Quality Central eingereicht und stelle # 100561 .

Als Workaround empfehle ich Ihnen, ein dynamisches Array zu verwenden, das Sie mit SetLength im Konstruktor zuweisen. Ich stelle mir eher vor, dass das Vorhandensein eines generischen Arrays fester Größe dazu führt, dass der Compiler sich schlecht verhält.

    
David Heffernan 28.10.2011, 18:38
quelle