Dynamic Array of Delphi 4
The array size of traditional Pascal is pre-determined. When you declare the data type with an array structure, you must specify the number of array elements. Professional programmers may know a little about the implementation technology of dynamic arrays. Generally, they use pointers to manually allocate and release the required memory.
In Delphi 4, a very simple dynamic array implementation method is added. The implementation process is similar to the dynamic long string I mentioned earlier. Like long strings, the memory of dynamic arrays is dynamically allocated and referenced. However, dynamic arrays do not support copy-on-write. This is not a big problem, because you can set the variable value to nil to release the Array Memory.
In this way, you can declare an array that does not specify the number of elements and allocate a memory of a specific size to the Array Using the SetLength process. The SetLength process can also change the size of the array without affecting its content, in addition, some character string procedures can also be used in arrays, such as the Copy function.
The following excerpt highlights the following code: After defining an array, you must allocate memory for it before using it:
procedure TForm1.Button1Click(Sender: TObject);var Array1: array of Integer;begin Array1 [1] := 100; // error SetLength (Array1, 100); Array1 [99] := 100; // OK ...end;
If you only define the number of elements in an array, the index always starts from 0. Normal arrays in Pascal can use non-zero subscripts or non-integer subscripts, but dynamic arrays do not support these two subscripts. Like an ordinary array, you can use the Length, High, and Low functions to understand the status of dynamic arrays. However, for dynamic arrays, the Low function always returns 0 values, and the High function returns an array size minus 1, this means that the High return value of the function of an empty dynamic array is-1, which is a strange value because it is smaller than the Low return value.
The above is a brief introduction. Here is a simple example named DynArr, as shown in Figure 8.1. The example is actually very simple. In fact, dynamic arrays are not particularly complicated. I want to use this example to illustrate the possible mistakes made by several programmers. The program declares two full-course arrays and initializes the first array in the OnCreate event:
var Array1, Array2: array of Integer;procedure TForm1.FormCreate(Sender: TObject);begin // allocate SetLength (Array1, 100);end;
In this way, all values of the array are set to 0. After this code is complete, you can read and write the values of array elements immediately without fear of memory errors. Of course, the condition is that you have not attempted to access elements that exceed the upper bound of the array. For better initialization, a button is added to the program to perform the array element assignment operation:
procedure TForm1.btnFillClick(Sender: TObject);var I: Integer;begin for I := Low (Array1) to High (Array1) do Array1 [I] := I;end;
The Grow button is used to modify the array size, but does not affect the array content. After you click the Grow button, you can use the Get value button for verification:
procedure TForm1.btnGrowClick(Sender: TObject);begin // grow keeping existing values SetLength (Array1, 200);end;procedure TForm1.btnGetClick(Sender: TObject);begin // extract Caption := IntToStr (Array1 [99]);end;
The OnClick Event code of the Alias button is a little more complex. The program copies an array to another array through the: = Operator, thus effectively creating an Alias (a new variable, but references the same Array in memory ). It can be seen that if you change one of the arrays, the other will also change because they point to the same memory zone:
procedure TForm1.btnAliasClick(Sender: TObject);begin // alias Array2 := Array1; // change one (both change) Array2 [99] := 1000; // show the other Caption := IntToStr (Array1 [99]);
Two operations are added to the btnAliasClick event. The first part is an array equivalent test, but it is not a test of the actual array elements, but a test of the memory zone referenced by the array. It checks whether the variables are two aliases of the same Array in memory:
procedure TForm1.btnAliasClick(Sender: TObject);begin ... if Array1 = Array2 then Beep; // truncate first array Array1 := Copy (Array2, 0, 10);end;
The second part of the btnAliasClick event is to call the Copy function. This function not only moves data from one array to another, but also replaces the first array with the new array created by the function. The result variable Array1 references the array of 11 elements. Therefore, pressing the Get value and Set value buttons will generate a memory error and trigger an exception (unless you disable the range Check range-checking option, in this case, the error is still present, but no exception is displayed on the screen ). Even so, the Fill button still works normally, because the array elements to be modified are determined by the current subscript range of the array.