Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Verwendung von Dyn.Array endet in AccessViolation


alias5000 - So 31.08.08 21:30
Titel: Verwendung von Dyn.Array endet in AccessViolation
Hallo zusammen,
das Thema ist nicht ganz so simpel, wie es vielleicht klingt (oder vielleicht doch).
Aber ich habe in der folgenden Sache etwas festgestellt, wo ich gerne den Hintergrund dazu wissen würde. Das Problem selbst kann ich ohne Probleme z.B. mit ner TStringList umgehen, kein Thema.

Also folgendes:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
interface

type

TStringArray = array of string;

implementation
[url]
[...][/url]

var
arr: TStringArray
begin
  SetLength(Arr, 8+festeZahl);
  Arr[1] := EinString;
  Arr[2] := Eine String-Property
  usw.
end;


Wenn ich das so verwende, bekomme ich am Ende(!) der Methode eine AccessViolation, deren Callstack folgendes besagt (daher auch meine Vermutungen):

Quelltext
1:
2:
3:
4:
5:
6:
00401c3d +081 TestClient.exe System          42  +0 SysFreeMem
00402d64 +004 TestClient.exe System          42  +0 @FreeMem
004050bd +021 TestClient.exe System          42  +0 @LStrArrayClr
00405cce +056 TestClient.exe System          42  +0 @FinalizeArray
0040678f +02b TestClient.exe System          42  +0 @DynArrayClear
0050ed21 +461 TestClient.exe LCMPConnection 263 +60 TLCMPConnection.ConfirmOnline


Ist die Deklaration eines TStringArray so ein No-Go? (der Zweck, warum, ist ja erstmal egal).
Das alles klingt danach, als ob sich die Compiler-Magic verschlucken würde!?

Gruß
alias5000

Edit: der Edit-War soll ein Ende haben.


BenBE - Fr 05.09.08 20:49

Kannst Du den Source mal bitte soweit aufräumen, dass man auch nachvollziehen kann, was du vor hast? Wenn da also 3 Compiler-Fehler weniger drin wären, würde das das Verständnis schon erheblich vereinfachen ;-)

Die Compiler-Magic hat aber auch gern einen Schluckauf, wenn man Strings (auch innerhalb von Arrays) uninitialisiert lässt ...


alias5000 - Fr 05.09.08 21:00

hmpf, ich hatte mich an dem Problem nicht so lange aufhalten wollen und habe die TStringList-Lösung umgesetzt, ohne vorher eine svn-rev zu machen. Ich kanns vereinfacht nicht reproduzieren und im Großen wie gesagt auch nicht.
Ich kann nicht ausschließen, dass ich mich bei der Zahl der Länge des Arrays vertan habe und dann die CompilerMagic sich auch vertan hat. Sollte ich das wieder reproduzieren können, sag ich was.

Code, mit dem ich das versuch habe, zu wiederholen:

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:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
unit Unit11;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TStringArray = array of string;
  TForm11 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    procedure DoSth(arr: TStringArray);
    { Public declarations }
  end;

var
  Form11: TForm11;

implementation

{$R *.dfm}

procedure TForm11.btn1Click(Sender: TObject);
var
  arr: TStringArray;
begin
  SetLength(arr, 3);
  arr[0] := 'Hallo';
  arr[1] := self.Caption;
end;

procedure TForm11.DoSth(arr: TStringArray);
begin
  showmessage(Arr[0]);
end;

end.

dfm lasse ich jetzt weg

Gruß
alias5000


BenBE - Fr 05.09.08 21:04

tsssss ... SVN haben und nicht nutzen!1!!

Ne, Spaß bei Seite. Eine mögliche Erklärung ist wie gesagt in meinem vorigen Post bereits enthalten, was durchaus zu SEHR merkwürdigen Ergebnissen führen kann. Hatte schon mal ein uninitialisiertes Array, wo ich mich gewundert hab, warum Delphi "beim Verlassen" der Prozedur immer 1-2 Sekunden brauchte. War im Endeffekt ein vergessenes SetLength, wo Delphi dann uninitialisierten Speicher hergenommen hat und ein (zufälliges) Array von 1,5 GB freigegeben hat (was nie alloziiert wurde) ... Lokale Variable usw halt ...