Current location - Loan Platform Complete Network - Big data management - What's the difference between delphi TStringList and String?
What's the difference between delphi TStringList and String?
T string list

It is a string list type, managed by PASCAL system and used as an array, but its size is dynamic, that is, it is essentially realized by a linked list, based on the linked list data structure. This thing is very common, and it is often used to organize a bunch of strings, that is, data of type String. There are many sayings about the usage of TStrigList on the Internet, which can be downloaded by Baidu.

String is the data type that stores strings.

Introduction of string type principle in Delphi

The operation of strings in Delphi is simple, but the situation behind the scenes is quite complicated. Pascal's traditional string manipulation method is different from Windows, and it absorbs the string manipulation method of C language. 32-bit Delphi adds a long string type, which is powerful and is the default string type of Delphi.

String type In TurboPascal and Borland's 16-bit Delphi, the traditional string type is a character sequence, and the head of the sequence is a length byte, indicating the length of the current string. Because only one byte is used to represent the length of the string, the string cannot exceed 255 characters. This length limitation brings inconvenience to string operation, because the length of each string must be fixed (the maximum value is 255), of course, you can also declare shorter strings to save storage space.

String types are similar to array types. In fact, a string is almost an array of character types, so the fact that you can access the characters in the string with the [] symbol fully illustrates the above point.

In order to overcome the limitations of traditional Pascal strings, 32-bit Delphi adds support for long strings. Therefore * * * has three types of strings:

Short string

The short chord type is also the traditional Pascal chord type mentioned above. This string can only have 255 characters at most, just like the string in 16-bit Delphi. Every character in a short string belongs to

ANSIChar type (standard character type).

distribute

The long string type is a newly added variable length string type. This string is dynamically allocated in memory, using reference counting and copy-on-write technology. The length of this string is not limited (it may

Store up to 2 billion characters! ), whose character type is also ANSIChar type.

Wide chord

Long string types and assignments

The type is similar, except that it is based on the WideChar character type, which is a double-byte Unicode character.

Use long strings

If a string is simply defined as a string, it may be a short string or an ANSI long string, depending on the value of the $H compilation instruction, and $ h+(exact provision) represents a long string (ANSIString type). Long strings are strings used by controls in Delphi library.

Delphi long string is based on reference counting mechanism, which tracks the string variables that refer to the same string in memory through reference counting. When the string is no longer used, that is, the reference count is zero, the memory is released.

If you want to increase the length of a string, and there is no free memory in the adjacent position of this string, that is, there is no room for expansion of this string in the same storage unit, then this string must be completely copied to another storage unit. When this happens, the Delphi runtime support program will reallocate memory for the string in a completely transparent way. In order to allocate the required storage space effectively, you can use the SetLength procedure to set the maximum length of a string, for example:

Set length

(String 1,

200);

The SetLength process only completes a memory request and does not actually allocate memory. It just reserved the memory needed in the future, but it didn't actually use this memory. This technology originated from the Windows operating system and is now being

Delphi is used to dynamically allocate memory. For example, when you request a large array, the system will reserve the array memory, but will not allocate the memory to the array.

Generally, there is no need to set the length of a string, but when you need to pass a long string as a parameter to an API function (after type conversion), you must use SetLength to reserve memory space for the string, which I will explain later.

Look at the string in memory.

In order to help you better understand the memory management details of strings, I wrote a simple example StrRef. In the program, I declared two complete strings: Str 1 and Str2. When the first button is pressed, the program assigns a string constant to the first variable, and then assigns the first variable to the second variable:

Str 1

:=

Hello;

Str2

:=

str 1;

In addition to string operations, the program also uses the following StringStatus function to display the internal state of a string in a list box:

function

String state

(Constant

Str:

String):

String;

begin

result

:=

Address:

'

+

IntToStr

(Integer

(Str))

+

,

Length:

'

+

IntToStr

(Length

(Str))

+

,

References:

'

+

IntToStr

(Pinteger

(Integer

(Str)

-

8)^)

+

,

Value:

'

+

Str

End;

In the StringStatus function, it is very important to pass a string with constant parameters. Passing by copying (value parameter) will have side effects, because an extra reference to the string will be generated during the execution of the function; On the contrary, passing by reference (var) or constant (const) parameters will not produce this situation. Because this example does not want the string to be modified, the constant parameter is selected.

In order to obtain the memory address of a string (which is helpful to identify the actual content of the string and to observe whether two different string variables refer to the same memory area), I cast the string type into an integer by type mapping. A string is actually a reference, that is, a pointer: a string variable holds the actual memory address of the string.

In order to extract the reference count information, I used a little-known fact: the string Length and reference count information are actually stored in the string, in front of the actual content and the memory location pointed by the string variable, and its negative offset is -4 for the string length (this value can be easily obtained by using the length function) and -8 for the reference count.

However, it must be remembered that the above internal information about offset may change in the future version of Delphi, and it is difficult to guarantee that the features that are not written into Delphi official documents will remain unchanged in the future.

By running this example, you will see that these two character strings have the same content, the same memory location and reference count of 2, as shown at the top of the list box in Figure 7. 1 Now, if you change the value of one of the strings, the memory address of the updated string will also change. This is the result of copy-on-write technology.

The OnClick event code of the second button (Change) is as follows, and the result is displayed in the second part of list box 7. 1:

procedure

TFormStrRef。 BtnChangeClick (from:

to object);

begin

Str 1

[2]

:=

a’;

List box 1. Projects. Add

(' Str 1

[2]

:=

'' a'');

List box 1. Projects. Add

(' Str 1

-

'

+

String state

(str 1));

List box 1. Projects. Add

(' Str2

-

'

+

String state

(str 2));

End;

Please note that BtnChangeClick can only be executed after BtnAssignClick. Therefore, the second button cannot be used after the program is started (the Enabled property of the button is set to false); When the first method is finished, activate the second button. You are free to extend this example and use the StringStatus function to explore the characteristics of long strings in other situations.

Dynamic allocation can use any memory allocation function,

In fact, the system finally calls GetMem.

Other New, AllocMem, SetLength, etc. Just do some initialization besides calling GetMem, such as clearing the memory. Release can be done with Dispose or FreeMem,

The system finally calls FreeMem,

Dispose is equivalent to finalize (p);

FreeMem(p);

The function of Finalize is only to automatically release strings and dynamic arrays in structures or arrays.

FreeMem directly releases the memory pointed by the pointer, for example:

type

TMyRec

=

record

Name:

String;

x,

y:

Integer;

End;

PMyRec

=

^tmyrec;

defined variable

Merek

PMyRec

begin

New (myrec);

//

The compiler will automatically calculate the amount of memory to be allocated according to the size of MyRec, and then generate code to call GetMem and clear the Name field in it.

Merek name

:=

str 1

+

str2

Disposal (myrec);

//

In addition to calling FreeMem to release the memory of MyRec structure, it will also automatically empty the memory used by Name (if the string reference count pointed by Name =1);

//

FreeMem(my rec);

& lt-

If FreeMem is directly called to release MyRec,

This will lead to a memory leak,

Because the string MyRec was referring to. Name not published (reference count-1).

End;

Because of the particularity of delphi's memory management of strings,

There are many technologies that can make full use of its advantages to generate very efficient code.

For example, using TList to save strings instead of TStringList,

The usual practice is to save a PString pointer in TList. Item [i].

So you need to reallocate a piece of memory and copy the original string.

The efficiency is very low in the case of a large amount of data,

But if you make full use of the reference counting and forced type conversion skills of string,

You can directly save the string as a pointer in TList. Item [i]:

For example:

defined variable

List:

TList

GlobalString 1,

Global string 2:

String;

...

procedure

Testing;

defined variable

tmp:

String;

begin

Terminal Monitor Program (abbreviation of terminal monitor program)

:=

global string 1+global string 2;

List. Add (pointer (tmp)););

//

Save tmp as a pointer to the list.

{

Since tmp is automatically released at the end of the test process,

If you exit directly, an invalid pointer will be saved in the list.

So we have to cheat the compiler,

Make it think that tmp has been released,

It is equivalent to executing tmp without changing the tmp reference count (currently 1).

:=

The statement of "",

Due to direct tmp

:=

The reference count will be modified and memory may be freed.

So we use a cast to convert tmp to an integer and set this integer to 0 (that is, nil).

This statement is completely equivalent to a pointer (tmp)

:=

Zero;

Just a personal preference. I like to use integer (tmp)

:=

Only 0.

}

Integer (tmp)

:=

0;

End;

1.

Delphi compiler internally supports strings (predefined

or

Built-in) is a basic data type of Delphi, and PChar is just a pointer to a string ending in zero;

2.

line

The stored string allocates memory in the heap. The string variable is actually a pointer to a zero-terminated string, and it also has a reference count (reference

Count) function, and save the string length. When the reference count is zero, the occupied space is automatically released.

3. Assigning a character string to another character string is just a simple pointer assignment, which does not produce a copy action, but only increases the reference count of the character string;

4. Assign the PChar variable type to the string.

Variable types will produce a real copy action, that is, the entire string pointed by PChar will be copied to the memory allocated for string;

5. Assigning string to PCCAR variable type only assigns the pointer value of string to PCCAR variable type, and the reference count of string will not change because of this operation, because PCCAR will depend on string in this case. When the reference count of string is zero, PCCAR is likely to point to an invalid memory address, so this situation must be handled carefully in the program.

6.PCCar is much faster than string, but PCCar is a backward way to manage string, and string wins with efficient management. PCCar exists only to be compatible with early types and operating systems (calling Windows).

Often used in API), it is recommended to use string normally.