Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

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

Re: Speicheranspruch Leerstring in Konstante

  Alt 29. Dez 2007, 03:06
Code- oder DatenSegment ist erstmal egal, wird doch eh nur in den Speicher reingemappt?
Also belegt nur virtuellen und keinen reellen RAM.
Und das EXE-Packer/-Crypter das Speichermanagement zerstören sollte bekannt sein. (also ignoriert)

Delphi-Quellcode:
Const
  S1 = '123';
  i1 = 123;
  S2: String = '234';
  i2: Integer = 234;

Procedure P1;
  Const
    S3 = '345';
    i3 = 345;
    S4: String = '456';
    i4: Integer = 456;

  Begin
    Form1.Memo1.Lines.Add(Format('S3 $%.8x $%.8x = "%s"', [0, Integer(@S3[1]), S3]));
    Form1.Memo1.Lines.Add(Format('i3 $%.8x = %d', [0, i3]));
    Form1.Memo1.Lines.Add(Format('S4 $%.8x $%.8x = "%s"', [Integer(@S4), Integer(S4), S4]));
    Form1.Memo1.Lines.Add(Format('i4 $%.8x = %d', [Integer(@i4), i4]));
  End;

Procedure P2;
  Const
    i5 = 567;

  Begin
    Form1.Memo1.Lines.Add(Format('i5 $%.8x = %d', [0, i5]));
  End;

Procedure TForm1.FormCreate(Sender: TObject);
  Var
    S6: String;
    i6: Integer;

  Begin
    S6 := '678';
    i6 := 678;

    Memo1.Lines.Clear;
    Memo1.Lines.Add(Format('S1 $%.8x $%.8x = "%s"', [0, Integer(@S1[1]), S1]));
    Memo1.Lines.Add(Format('i1 $%.8x = %d', [0, i1]));
    Memo1.Lines.Add(Format('S2 $%.8x $%.8x = "%s"', [Integer(@S2), Integer(S2), S2]));
    Memo1.Lines.Add(Format('i2 $%.8x = %d', [Integer(@i2), i2]));
    Memo1.Lines.Add(Format('P1 $%.8x', [Integer(@P1)]));
    P1;
    Memo1.Lines.Add(Format('P2 $%.8x', [Integer(@P2)]));
    P2;
    Memo1.Lines.Add(Format('S6 $%.8x $%.8x = "%s"', [Integer(@S6), Integer(S6), S6]));
    Memo1.Lines.Add(Format('i6 $%.8x = %d', [Integer(@i6), i6]));
    UniqueString(S6);
    Memo1.Lines.Add('');
    Memo1.Lines.Add(Format('S6 $%.8x $%.8x = "%s"', [Integer(@S6), Integer(S6), S6]));
    Memo1.Lines.Add('');
    Memo1.Lines.Add('');
    Memo1.Lines.Add('$00000000 = inline Konstante ... wird direkt im Code ersetzt');
  End;
Raus kommt dann etwa sowas:
- Erstes = Position der Variable/Konstante
- Zweites = Position der Stringdaten (des Inhaltes)
Zitat:
S1 $00000000 $0044F334 = "123"
i1 $00000000 = 123
S2 $00450D9C $0044EC68 = "234"
i2 $00450DA0 = 234

P1 $0044EC78
S3 $00000000 $0044EE0C = "345"
i3 $00000000 = 345
S4 $00450DA4 $0044EC74 = "456"
i4 $00450DA8 = 456

P2 $0044EEA8
i5 $00000000 = 567

S6 $0012FE18 $0044F328 = "678"
i6 $0012FE14 = 678

S6 $0012FE18 $008D2290 = "678"


$00000000 = inline Konstante ... wird direkt im Code ersetzt

Pascal-Definition der delphiinternen Typen (Auszug):
Delphi-Quellcode:
Type TShortStringInfo = packed Record // PShortStringInfo := @Var
    Len: Byte;
    Chars: packed Array[1..255{1..Len}] of Char;
  End;
  PShortStringInfo = ^TShortStringInfo;

(*************************************************************************** )
(                                                                            )
(  P___Info    := Pointer(var) - SDynArrayInfo                              )
(  Pointer(var) := T___Info.___Addr                                          )
(                                                                            )
(  A String/AnsiString is an packed Array of Char and just the same as near the )
(  packed Array of Char an additional #0 is attached also there still behind.  )
(  (for the PChar compatibility)                                            )
(                                                                            )
(  The WideString and the packed Array of WideChar are also identical        )
(  and there #0#0 hide themselves behind that.                              )
(                                                                            )
(*************************************************************************** )
(                                                                            )
(  T___Info / P___Info:                                                      )
(  ********************                                                      )
(                                                                            )
(  Pointer(var)      = nil        > nil {in EXE}        > nil {in RAM}      )
(                                                                            )
(  RefCount          -            = -1                  > 0                )
(  ElementCount      -            > 0, = Length(var)    > 0, = Length(var)  )
(  Data              -            = var                = var              )
(                                                                            )
(****************************************************************************)


Const SDynArrayInfo = 2 * SizeOf(LongInt);

Type TDynArrayInfo = packed Record
    RefCount: LongInt;
    ElementCount: LongInt;
    Data: packed Array[0..High(Integer) - SDynArrayInfo - 1] of Byte;
  End;
  TAnsiStringInfo = packed Record
    RefCount: LongInt;
    ElementCount: LongInt;
    Data: packed Array[1..High(Integer) - SDynArrayInfo] of AnsiChar;
  End;
  TWideStringInfo = packed Record
    RefCount: LongInt;
    ElementCount: LongInt;
    Data: packed Array[1..(High(Integer) - SDynArrayInfo) div 2] of WideChar;
  End;

Aber nochmal zum Thema: 4 Byte pro Leer-String und diese müssen nicht im RAM liegen.
$2B or not $2B
  Mit Zitat antworten Zitat