Re: This is getting really weird.
From: Rob Kennedy (me_at_privacy.net)
Date: Sat, 21 Feb 2004 12:59:39 -0600
Skybuck Flying wrote:
> You say, one has to allocate a string, ok I do that like so:
> New( Pstring(Storage) );
> So far so good (I think)... it allocates 8 bytes.
Makes sense. Four bytes for SizeOf(string) plus another four bytes that
the memory manager uses for its own bookkeeping.
> Now when 10 bytes are assigned like so:
> AnsiString(Storage) := '1234567890'; // 20 bytes are allocated ?!
There should be no memory allocation for that line. The string is a
constant. It resides in the data segment, and its reference count is
permanently set to -1 -- an indication to the string manager that the
memory should never be freed.
Anyway: Ten bytes for the characters, four for the reference count, four
for the length, and one for the terminating null. That's 19. The memory
manager may allocate more space than requested for its own efficiency.
(It helps for memory to be "aligned" to certain byte boundaries, which
are always even, so the memory manager would never use the leftover byte
as the start of a separately allocate block -- its address is odd. The
memory manager instead includes the last byte with the string's memory
block. You could probably append an eleventh character to the string
without triggering any memory re-allocation.)
> Now comes the weirdest part:
> AnsiString(Storage) := ''; // 20 bytes freeed ?!
> BUTTTTTTT what about the other 8 bytes ?!?!
They're lost forever. You orphaned them when you assigned the 10-byte
string to Storage above.
You allocated space to a string variable on the heap. You stored a
pointer to that heap space in Storage. That's what New does -- it
allocates space. The Storage variable itself occupies four bytes that
you don't need to allocate. (You don't need to allocate them specially,
anyway; they're allotted when you create the object that Storage belongs
However, when you assigned a string to Storage, to overwrote the pointer
that New returned with a pointer to the string constant. If you treat
Storage as a PString when you allocate space, then you must *treat* it
as a PString whenever you use it. Your code should have gone like this:
PString(Storage)^ := '1234567890';
> Anyway let's ignore the missing 8 bytes let's assume everything is just fine
> ?! which it s not i think :)
No, it's not fine. Not by a long shot.
> Suppose I now want to assign a new string !
> This raises the interesting question: "Do I have to 're-new' the storage?"
> In other words do I have to call New again ?!
No. When you want to assign a string, you always use the := operator.
> The answer is probably: No ! because that would explain the missing 8 bytes
> They are still allocated ?!
> Euhm this again raises a new interesting question: "How do I get rid of the
> remaining 8 bytes ?!"
Since you allocated them with New, release them with Dispose. But don't
overwrite your reference to them in the meantime.
> Lol, maybe this is a delphi bug hehehehe... Because Dispose aint working ?!?
No, it's not a Delphi bug. It's been the way Borland's language has
worked since the beginning. Just because something isn't working the way
you expect it to work doesn't mean it's working incorrectly.