ich schreibe grade ein Programm welches aus einer Datei verschiedene Daten, Objektproperties ausliest. Das auslesen klappt soweit auch ganz gut, nur jetzt habe ich ein kleines Problem. Sobald das Programm aus der Lesemethode raus springt bekomme ich eine Zugriffsverletzung bei der funktion fpc_ansistr_decr_ref, also der Funktion um den Referenzzähler eines Strings zu reduzieren.
Ich bin komplett ratlos warum. Der Code, stark reduziert da es sich sonst um über 150 Zeile handeln würde:
Code: Alles auswählen
procedure TMoverProperties.Load(Prop, PropText: TBytes;
DefO, DefN, DefA, DefI, DefS: TConstReader);
function GetID(Key: string): longword;
var
tmp: string;
begin
TTextReader.SplitKey(Key, tmp, Result);
end;
var
script: TScriptReader;
i: integer;
proptxt: TTextReader;
tmp: PMoverProperty;
var
Tok: string;
begin
FDefO := DefO;
FDefN := DefN;
FDefA := DefA;
FDefI := DefI;
FDefS := DefS;
script := TScriptReader.Create(Prop);
proptxt := TTextReader.Create(PropText);
try
while not (script.EndOfFile) do
begin
New(tmp);
FillChar(tmp^, SizeOf(TMoverProperty), #00);
script.ReadToken(tok);
tmp^.ID := FDefO.GetConstByKey(Tok).uValue;
script.ReadToken(tok);
tmp^.Name := proptxt.KeyText[tok];
tmp^.NameID := GetID(Tok);
script.ReadToken(tok);
tmp^.DefaultVal := FDefN.GetConstByKey(tok).uValue;
tmp^.DS1 := script.GetInteger;
tmp^.DS2 := script.GetInteger;
tmp^.DS3 := script.GetInteger;
tmp^.DA1 := script.GetInteger;
tmp^.DA2 := script.GetInteger;
tmp^.ER1 := script.GetInteger;
tmp^.ER2 := script.GetInteger;
// viele mehr solcher zeilen
Props.Add(tmp);
end;
finally
script.Free;
proptxt.Free;
end;
end;
Code: Alles auswählen
procedure TForm1.FormCreate(Sender: TObject);
procedure FillWithPrefix(sl: TStrings; c: TConstReader; pref: String);
var i: Integer;
begin
sl.Add('-');
for i:=0 to c.Count-1 do
if AnsiStartsStr(pref, c.Constants[i].Key) then
sl.Add(Format('%s - %d', [c.Constants[i].Key, c.Constants[i].uValue]));
end;
var defn, defo, defa, defi, defs, pm, ptxt: TBytes;
fs: TFileStream;
p: String;
begin
// Dateien über FileStream in Arrays laden hab ich übersprungen
FDefN:=TConstReader.Create;
FDefI:=TConstReader.Create;
FDefA:=TConstReader.Create;
FDefO:=TConstReader.Create;
FDefS:=TConstReader.Create;
FDefN.Read(defn, '');
FDefA.Read(defa, '');
FDefI.Read(defi, '');
FDefO.Read(defo, '');
FDefS.Read(DefS, '');
Movers:=TMoverProperties.Create;
Movers.Load(pm, ptxt, DefObj, DefNeuz, DefAttr, DefItem,DefSound);
...
Code: Alles auswählen
procedure TScriptReader.ReadToken(out tok: string);
begin
tok := '';
repeat
tok := tok + FLine[FPosition];
Inc(FPosition);
until (FPosition > Length(FLine)) or (FLine[FPosition] in [' ', #9]);
ReadToNext;
end;
procedure TScriptReader.ReadInteger(out i: integer);
var
s: string;
begin
ReadToken(s);
if s[Length(s)] = ',' then
s := Copy(s, 1, Length(s) - 1);
if AnsiStartsText('0x', s) then
begin
i := Hex2Dec(Copy(s, 3, Length(s) - 2));
end
else if s = '=' then
i := -1
else if s = 'FALSE' then
i := 0
else if s = 'TRUE' then
i := 1
else
i := StrToInt(s);
end;
An der TScriptReader Klasse kann es eigentlich nicht liegen, die funktioniert bei allen anderen Projekten problemlos.
Lazarus Trunc und fpc 3.0.0rc2 Windows 10 64 Bit, anwendung ist 32 Bit
PS: Ich weiß dass die ReadToken methode recht ineffizient ist, die quelltext datei ist etwas älter und ich kam noch nicht dazu sie zu verbessern