Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi StrAlloc verstehen (https://www.delphipraxis.net/96915-stralloc-verstehen.html)

Neutral General 1. Aug 2007 15:29


StrAlloc verstehen
 
Hi,

Habe mir gerade angeguckt wie man per Drag&Drop Dateien aus dem Explorer öffnet.. Habe soweit alles verstanden aaaber..

Delphi-Quellcode:
size := DragQueryFile(Msg.WParam, i , nil, 0) + 1;
Filename:= StrAlloc(size);
Man holt sich hier die größe des FilenameStrings... Wie das funktioniert habe ich mithilfe der Hilfe verstanden. Aber wie man nun nur durch die Größe an den eigentlichen String kommt nicht so ganz...
Ich kommentier mal soweit ich das nachvollziehen kann..


Delphi-Quellcode:
function StrAlloc(Size: Cardinal): PChar;
begin
  Inc(Size, SizeOf(Cardinal)); //warum?
  GetMem(Result, Size); // Speicher reservieren .. soviel wie der String lang ist
  Cardinal(Pointer(Result)^) := Size; // Size stellt die Adresse des Strings dar?
                                      // Hiermit wird doch der Pointer von Result auf die Adresse
                                      // die Size darstellt (mir fällt keine bessere Beschreibung ein)
                                      // "umgelenkt"
  Inc(Result, SizeOf(Cardinal));     // warum?
end;
Was ich daran nicht verstehe ist das Size sowohl die Länge als auch gleichzeitig die Speicheradresse des Strings darstellt.. Wenn der String 2 Zeichen lang ist.. dann müsste der String doch beim Offset 02 anfangen oder verstehe ich da was falsch?

Gruß
Neutral General

sirius 1. Aug 2007 15:36

Re: StrAlloc verstehen
 
Delphi-Quellcode:
function StrAlloc(Size: Cardinal): PChar;
begin
  Inc(Size, SizeOf(Cardinal)); //Die Größe des zu reservierenden Platzes um 4 Bytes erhöhen
  GetMem(Result, Size); // Speicher reservieren .. soviel wie der String lang ist + 4 Bytes um die Länges des Strings zu speichern
  Cardinal(Pointer(Result)^) := Size; //die Größe des Speicherplatzes am Anfang des reservierten Platzes speichern
  Inc(Result, SizeOf(Cardinal)); // Den Pointer (PChar) hinter die Größenangabe verschieben    
end;
Ein PChar sieht bei Delphi so aus, dass immer vor dem PChar 4 Bytes mit reserviert werden, welche die Länge des Strings beinhalten (+4)

Christian Seehase 1. Aug 2007 15:40

Re: StrAlloc verstehen
 
Moin Michael,

der Inhalt eines "normalen" Strings in Delphi beginnt bei der Adresse, die die Funktion zurückliefert.
Davor liegen dann noch 4 Byte (als Cardinal) Länge (und davor noch 4 Byte Referenzcount. Wo sind die eigentlich :gruebel:)

Delphi-Quellcode:
  // Platz schaffen für die Länge des zu reservierenden Strings
  Inc(Size, SizeOf(Cardinal));
  // Speicher reservieren für Länge und Inhalt
  // Result enthält jetzt die Adresse des reservierten Speichers
  GetMem(Result, Size);
  // An dieser Stelle wird jetzt die Länge gespeichert
  // Durch das ^ wird dereferenziert, also an die Adresse geschrieben, auf die Result zeigt.
  // Durch Cardinal() wird dann ein Type-Cast durchgeführt, damit man auch Size dorthin schreiben kann,
  // was der Compiler sonst unterbinden würde
  Cardinal(Pointer(Result)^) := Size;
  // Jetzt wird Result auf den Anfang des Inhaltes gesetzt
  // Die Länge steht also auf Result - 4
  Inc(Result, SizeOf(Cardinal));

thkerkmann 1. Aug 2007 15:42

Re: StrAlloc verstehen
 
Hi,

warum so kompliziert ?

Delphi-Quellcode:
...
var
  Filename: string;
...

   size := DragQueryFile(Msg.WParam, i , nil, 0);
   SetLength(Filename,size);
   size := DragQueryFile(Msg.WParam, i, pChar(Filename), 0);

...
ungetestet, müsste aber stimmen.

Gruss
[Edit thkerkmann] Mist, Thema verfehlt.... 6 setzen [/Edit]

Neutral General 1. Aug 2007 15:42

Re: StrAlloc verstehen
 
Ja gut was passiert hab ich jetzt verstanden aber der String könnte doch überall im Speicher sein.. Wieso zeigt Result standardmäßig schon am Anfang der Procedure (oder spätestens nach GetMem) auf das erste Zeichen des Strings ? (Müsste ja nach meinem Verständnis).

Wisst ihr was ich meine?

sirius 1. Aug 2007 15:45

Re: StrAlloc verstehen
 
Zitat:

Zitat von Christian Seehase
(und davor noch 4 Byte Referenzcount. Wo sind die eigentlich :gruebel:)

Ist ja kein String sondern ein PChar. Der hat keinen Referenzzähler :zwinker: .

Christian Seehase 1. Aug 2007 15:45

Re: StrAlloc verstehen
 
Moin Michael,

mit GetMem wird der Speicher reserviert, und die Adresse dieser Reservierung in Result abgelegt.

Der_Unwissende 1. Aug 2007 15:45

Re: StrAlloc verstehen
 
Hüstel verlesen, sorry!

Christian Seehase 1. Aug 2007 15:46

Re: StrAlloc verstehen
 
Sirius,

Zitat:

Zitat von sirius
Ist ja kein String sondern ein PChar. Der hat keinen Referenzzähler :zwinker: .

Schon, aber ein PChar braucht auch keine Länge... ;-)

sirius 1. Aug 2007 15:47

Re: StrAlloc verstehen
 
Zitat:

Zitat von Neutral General
Ja gut was passiert hab ich jetzt verstanden aber der String könnte doch überall im Speicher sein.. Wieso zeigt Result standardmäßig schon am Anfang der Procedure (oder spätestens nach GetMem) auf das erste Zeichen des Strings ? (Müsste ja nach meinem Verständnis).

Wisst ihr was ich meine?

Nö, der Zeiger zeigt nah GetMem auf den reservierten speicherplatz (inkl. der 4 Bytes) und wird am Ende (das "inc") einfach hinter die ersten 4 Bytes gelegt, also an den Anfang von [size] reservierten Bytes.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:59 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz