Ansistrings are strings that have no length limit. They are reference counted and null terminated. Internally, an ansistring is treated as a pointer. This is all handled transparantly, i.e. they can be manipulated as a normal short string. Ansistrings can be de ned using the prede ned AnsiString type.
If the f$Hg switch is on, then a string de nition using the regular String keyword and that doesn't contain a length speci er, will be regarded as an ansistring as well. If a length speci er is present, a short string will be used, regardless of the f$Hg setting.
If the string is empty (''), then the internal pointer representation of the string pointer is Nil. If the string is not empty, then the pointer points to a structure in heap memory.
The internal representation as a pointer, and the automatic null-termination make it possible to typecast an ansistring to a pchar. If the string is empty (so the pointer is nil) then the compiler makes sure that the typecasted pchar will point to a null byte.
Assigning one ansistring to another doesn't involve moving the actual string. A statement
S2:=S1;
|
results in the reference count of S2 being decreased by one, The referece count of S1 is increased by one, and nally S1 (as a pointer) is copied to S2. This is a signi cant speed-up in the code.
If the reference count reaches zero, then the memory occupied by the string is deallocated automatically, so no memory leaks arise.
When an ansistring is declared, the Free Pascal compiler initially allocates just memory for a pointer, not more. This pointer is guaranteed to be nil, meaning that the string is initially empty. This is true for local and global ansistrings or anstrings that are part of a structure (arrays, records or objects).
This does introduce an overhead. For instance, declaring
Var
A : Array[1..100000] of string; |
Will copy 100,000 times nil into A. When A goes out of scope, then the reference count of the 100,000 strings will be decreased by 1 for each of these strings. All this happens invisibly for the programmer, but when considering performance issues, this is important.
Memory will be allocated only when the string is assigned a value. If the string goes out of scope, then its reference count is automatically decreased by 1. If the reference count reaches zero, the memory reserved for the string is released.
If a value is assigned to a character of a string that has a reference count greater than 1, such as in the following statements:
S:=T; { reference count for S and T is now 2 }
S[I]:='@'; |
then a copy of the string is created before the assignment. This is known as copy-on-write semantics.
The Length (??) function must be used to get the length of an ansistring.
To set the length of an ansistring, the SetLength (??) function must be used. Constant ansistrings have a reference count of -1 and are treated specially.
Ansistrings are converted to short strings by the compiler if needed, this means that the use of ansistrings and short strings can be mixed without problems.
Ansistrings can be typecasted to PChar or Pointer types:
Var P : Pointer;
PC : PChar; S : AnsiString; begin S :='This is an ansistring'; PC:=Pchar(S); P :=Pointer(S); |
There is a di erence between the two typecasts. When an empty ansistring is typecasted to a pointer, the pointer wil be Nil. If an empty ansistring is typecasted to a PChar, then the result will be a pointer to a zero byte (an empty string).
The result of such a typecast must be used with care. In general, it is best to consider the result of such a typecast as read-only, i.e. suitable for passing to a procedure that needs a constant pchar argument.
It is therefore NOT advisable to typecast one of the following: