Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2001-11

StrAlloc and StrDispose of pChars and the like

4 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Cox, Stuart SRM:EX

I'd appreciate help on this newbie, dinosaur question.

pChar strings seem like a wonderful extension of the 255 char limit that Borland imposed when they originally designed TP. Despite repeated attempts to wring out bugs in my code I still seem to leave memory holes and have heap related crashes.

How does BP7 know how much memory to release when it comes time to free memory for a pChar string? The BP7 help says the following things:

"StrDispose disposes of a string that was previously allocated with StrNew. If Str is nil, StrDispose does nothing."

"StrNew allocates a copy of Str on the heap. If Str is nil or points to an empty string, StrNew returns nil and does not allocate any heap space. Otherwise, StrNew makes a duplicate of Str,
obtaining space with a call to the GetMem standard procedure, and returns a pointer to the duplicated string. The allocated space is StrLen(Str) + 1 bytes long."

On the other hand, Delphi 1's help file says:

"The StrDispose procedure disposes of a string on a heap that was previously allocated with StrNew. If Str is nil, StrDispose does nothing."

"StrAlloc. This function allocates a buffer for a null-terminated string with a maximum length of Size - 1 (1 byte must be reserved for the termination character). The maximum value of Size is 65,526. The result points to the location where the first character of the string is to be stored. A 16-bit number giving the total amount of memory allocated is stored in the two bytes preceding the first character; it is equal to Size +
2. If space for a string is allocated with StrAlloc, it should be deallocated via StrDispose. StrAlloc is used by NewStr and is a general purpose routine."

Are these two products, BP7 and Delphi 1, talking about the same TYPE? Does BP7 allocate a word sized memory allocation size indicator in memory preceding the actual location of the first char of the pChar string? If not, how does the humble programmer release the same amount of memory as he allocated to hold a long string that has become shorter during program operation?

Thanks

Reply by email

Rich Pasco
to Cox, Stuart SRM:EX
Are these two products, BP7 and Delphi 1, talking about the same TYPE?

Yes.

Does BP7 allocate a word sized memory allocation size indicator in memory preceding the actual location of the first char of the pChar string?

That's an implementation detail you don't really need to know about. As long as you pass the same pchar to StrDispose that you got from StrAlloc, everything should work out.

If not, how does the humble programmer release the same amount of memory as he allocated to hold a long string that has become shorter during program operation?

I don't think that you're supposed to edit these strings in place on the heap, certainly not truncate them by poking nulls into them.

- Rich

Reply by email

Cox, Stuart SRM:EX

Thanks Rich,

The implementation detail is important however. I purchased the RTL source for BP7 when it came out and then was given the same code with the Delphi 1 distribution CD.

There is no StrAlloc function in the BP7 RTL. The only allocation function that Borland supplied was the StrNew function which looked at the current length of an existing pChar then allocated and copied it to create a duplicate of the original as it exists at the current moment. The memory allocated to hold the original's original length was never consulted.

The net result is that, using the Borland supplied functions, one can only create shorter and shorter copies and cannot lengthen pChar strings.

If one is to create pChars you really need to allocate an array of char just like the example that Borland supplies with the introduction to pChars in the BP7 manual. They don't mention any invisible allocation word as being part of their implementation.

Without the programmer being told of the existence of the leading invisible allocation word, he's at a loss as to how long the memory buffer was first make. How long the string could become or how much memory is being used up.

Additionally, the StrDispose function, as written in the RTL, does not consult any invisible allocation word but rather just FreeMems the memory occupied by the pChar's current length plus the NUL.

I can't see how this combination of functions and the lack of any indicator within the data itself of the initial length of the memory allocation can possibly result in reliable programs.

Did Borland see the light with Delphi 1 and correct an oversight? Does Free Pascal follow the BP7 or Delphi 1 model?

Thanks again.

Stuart Cox
Map Generalization Technician, not
Forest Inventory and Monitoring Branch
Ministry of Sustainable Resource Management
······················································ Phone: (250)387-5529
FAX: (250)356-9430
email
View the FMIB Website at:
http://www.for.gov.bc.ca/resinv/homepage.htm

Earlier message 32 lines
-----Original Message----- From: Rich Pasco Sent: Tuesday, November 13, 2001 4:23 PM To: Subject: Re: [fpc-pascal]StrAlloc and StrDispose of pChars and the like "Cox, Stuart SRM:EX" wrote: > Are these two products, BP7 and Delphi 1, talking about the same TYPE? Yes. > Does > BP7 allocate a word sized memory allocation size indicator in memory > preceding the actual location of the first char of the pChar string? That's an implementation detail you don't really need to know about. As long as you pass the same pchar to StrDispose that you got from StrAlloc, everything should work out. > If > not, how does the humble programmer release the same amount of memory as he > allocated to hold a long string that has become shorter during program > operation? I don't think that you're supposed to edit these strings in place on the heap, certainly not truncate them by poking nulls into them. - Rich

Reply by email

Jonas Maebe
to Cox, Stuart SRM:EX
Show quoted text 7 lines
If one is to create pChars you really need to allocate an array of char just like the example that Borland supplies with the introduction to pChars in the BP7 manual. They don't mention any invisible allocation word as being part of their implementation.

FPC doesn't use an invisible word specifically for pchar's either (whether you allocate the memory with stralloc, getmem or whatever), because every heap block itself already contains information about its length. Further, the only thing stralloc does is call getmem with the same argument it received.

strdispose(p) is simply a wrapper for

if assigned(p) then
   begin
     freemem(p);
     p := nil;
   end;

The freemem call without a second parameter comes originally from Delphi and lets the heap manager find out how much memory was allocated to that pointer and release it.

To change the amount of memory allocated to a pointer (a pchar is a pointer to a char, so it works for those just as well), you can use reallocmem(p,new_size). And you can still use strdispose() later on...

Jonas

Reply by email