I have the method (Delphi 2009):
procedure TAnsiStringType.SetData(const Value: TBuffer; IsNull: boolean = False);
begin
if not IsNull then
FValue:= PAnsiS
An AnsiString
is implemented as a pointer. An AnsiString
variable holds nothing but an address. The address is that of the first character in the string, or nil
if the string is empty.
A PAnsiString
is a pointer to an AnsiString
variable. It's a pointer to a pointer to the first character of a string. When you say PAnsiString(Buffer)
, you're telling the compiler to treat the pointer in Buffer
as though it were a pointer to an AnsiString
instead of a pointer to character data. The address 5006500 is the location of the first character of the string, C
.
You have a record in memory that represents the string:
+-----------+ | $ffffffff | -1 reference count (4 bytes) +-----------+ Buffer: | $00000001 | length (4 bytes) +---------+ +-----------+ | 5006500 | --> | 'C' | first character (1 byte) +---------+ +-----------+ | #0 | null terminator (1 byte) +-----------+
Buffer
holds the address of the byte with C
in it. You type-cast that to have type PAnsiString
instead of AnsiString
. You told the compiler that you had this layout:
+-----------+ | ... | +-----------+ Buffer: | ... | +---------+ +-----------+ +-----------+ | 5006500 | --> | $00000043 | --> | garbage | first character +---------+ +-----------+ +-----------+ | ... | +-----------+
When I'm reasoning about pointers, I draw diagrams just like this. If you don't keep some paper next to you on your desk, you're doing yourself a disservice.