Ich habe versucht eine datenstruktur wie folgt aufzubauen, (records sind ja managed?)
Delphi-Quellcode:
Pnum = ^Tlargenum;
Tlargenum= Record
Private
FLength, Fchunkcount: Word;
FNext: pmyrec;
_ispositive: Boolean;
Const
_Chunkdigits = 10;
Type
Tdigit = 0 .. 9;
Var
FDigits: Array [0 .. _Chunkdigits - 1] Of Tdigit;
Private
Class Procedure Clear(Var A: Tlargenum); Static;
public
Constructor Create(Avalue: Pchar);
Procedure Free;
end
Da records keinen Destructor einführen habe ich die
class procedure
clear, welche rekursiv alles löschen soll:
Delphi-Quellcode:
Constructor Tlargenum.Create(Avalue: Pchar);
Var
Digitindex: Integer;
Begin
Inherited;
If Assigned(Avalue)
Then
Begin
If Avalue = '
'
Then
Create('
0')
Else
Begin
Fnext :=
Nil;
// Clear;
FLength := 0;
// System.Length(Avalue);
Fchunkdigitcount := 0;
Digitindex := 0;
// get sign
_ispositive := Avalue^ <> '
-';
If Not _ispositive
Then
Dec(Flength);
While Not(Avalue^
In ['
0' .. '
9'])
And (Avalue <>
Nil)
Do
Inc(Avalue);
While Avalue^ <> #0
Do
Begin
FDigits[Digitindex] := Strtoint(Avalue^);
Inc(Avalue);
Inc(Digitindex);
Inc(Fchunkdigitcount);
Inc(Flength);
If Digitindex = _Chunkdigits
Then
Begin
New(Fnext);
Fnext^ := Tlargenum.Create(Avalue);
Flength := Flength + Fnext^.Flength;
Break;
End;
End;
End;
End;
End;
Procedure Tlargenum.Free;
Begin
Clear(Self);
End;
Class Procedure Tlargenum.Clear(
Var A: Tlargenum);
Var
Temp: Pnum;
Adigit: Pbyte;
Begin
A._ispositive := False;
A.FLength := 0;
A.Fchunkdigitcount := 0;
Fillchar(A.Fdigits, System.Length(A.Fdigits), 0);
While Assigned(A.Fnext)
Do
Begin
Temp := A.Fnext;
A.Fnext := A.Fnext^.FNext;
Dispose(Temp);
End;
// Fmath := Nil;
End;
soweit sogut:
nun führe ich class operators ein:
Delphi-Quellcode:
Class Operator Implicit(A: Tlargenum): String; Overload; // OK
Class Operator Explicit(A: Tlargenum): Integer; Overload; // OK
Class Operator Explicit(A: Tlargenum): Byte; Overload; // OK
// Class Operator Explicit(A: String): Tlargenum; Overload;
Class Operator Implicit(A: Uint64): Tlargenum; Overload;
Class Operator Implicit(A: Int64): Tlargenum; Overload;
Class Operator Implicit(A: String): Tlargenum; Overload;
Delphi-Quellcode:
Class Operator Tlargenum.Implicit(A:
String): Tlargenum;
// Var
// Returnrec: Tlargenum;
Begin
Result := Tlargenum.Create(Pchar(A));
// Result := Returnrec;
End;
Class Operator Tlargenum.Implicit(A: Tlargenum):
String;
Var
I: Byte;
Begin
Result := '
';
I := 0;
While I < A.Fchunkdigitcount
Do
Begin
Result := Result + Inttostr(A.FDigits[I]);
Inc(I);
End;
If Assigned(A.FNext)
Then
Result := Result + A.Fnext^;
End;
Class Operator Tlargenum.Explicit(A: Tlargenum): Integer;
Begin
// ok:
Var
Temp: Tlargenum;
Temp := High(Integer);
Try
If A < Temp
Then
Result := Strtoint(A)
Else
Raise Eoverflow.Create('
Cant be converted into integer type');
// error
Except
On E:
Exception Do
Showmessage(E.
Message)
End;
Temp.Free;
{ If A > High(integer)
Then
Raise Exception.Create('Number cannot be converted into byte');
Result := Strtoint(A); }
End;
Class Operator Tlargenum.Explicit(A: Tlargenum): Byte;
Begin
Var
Temp: Tlargenum;
Temp := High(Byte);
If A > Temp
Then
Raise Exception.Create('
Number cannot be converted into byte');
Result := Strtoint(A);
Temp.Free;
End;
Class Operator Tlargenum.Implicit(A: Uint64): Tlargenum;
Var
Temp:
String;
Begin
Temp := UInttostr(A);
Result := Temp;
// Result.FLength := Length(Temp);
// Result._ispositive := True;
End;
Class Operator Tlargenum.Implicit(A: Int64): Tlargenum;
Begin
Result := Uint64(Abs(A));
Result._ispositive := A >= 0;
End;
Die jeweiligen Conversions werden korrekt durchgeführt, aber zb. implicit conversions wie
Delphi-Quellcode:
Assert(X > '3000000000000000');//x is vom typ tlargenum, der string wird implizit umgewandelt
Assert(X >= '3000000000000000');
führen zu leaks, da die impliziten records nie freigegeben werden.
Wie kann ich den speicher denn hier wieder sauber freigeben?
Danke