5.1.4 动态数组
在传统的Pascal中,数组的大小是固定的,并且在声明数据类型时限制了元素的数量。然而,Object Pascal支持动态数组的直接和本地实现。
注解:“直接实现动态数组” 与使用指针和动态内存分配来获得类似效果的方法截然不同… 后者代码非常复杂且容易出错。 顺便说一句,动态数组是大多数现代编程语言中唯一的一种结构形式。
动态数组是动态分配的,并进行引用计数(使得参数传递更快,因为只传递引用,而不是完整数组的副本)。当您完成使用数组时,可以通过将其变量设置为nil或将长度设置为零来清除数组,由于动态数组是引用计数的,编译器将自动释放内存。请注意,这仅适用于数组项使用的内存:如果数组保存对其他位置内存的引用(如对象引用),您需要确保在释放数组本身之前清理这些对象使用的内存。
使用动态数组时,您可以声明一个数组类型而不指定元素的数量,然后使用SetLength过程设置数组的大小:
var
Array1: array of Integer;
begin
// 这将导致运行时范围检查错误
// Array1[0] := 100;
SetLength(Array1, 10);
Array1[0] := 100; // 这是可以的
end;
在为数组设定长度并在堆上分配所需的内存之前,你不能使用数组。如果你这样做,要么会出现范围检查错误(如果相应的编译器选项处于激活状态),要么会在 Windows 平台上出现访问违规(Access Violation),或者在其他平台上出现类似的内存访问错误。SetLength 调用会将所有的值设置为零。数组初始化以后,你就可以立即开始读写数组值,而不必担心内存错误(除非超越了数组边界)。
如果确实需要显式分配内存,你也不必直接释放内存。在上面的代码片段中,当代码结束且 Array1 变量退出作用域时,编译器会自动释放其内存(在本例中