增加动态数组的大小会发生什么?

时间:2010-11-19 06:39:32

标签: delphi

我想了解当动态数组的大小增加时会发生什么。

到目前为止我的理解:

  • 现有数组元素将保持不变。
  • 新数组元素初始化为0
  • 所有数组元素在内存中都是连续的。

当数组大小增加时,是将额外的内存添加到现有内存块上,还是将现有元素复制到一个全新的内存块?

更改动态数组的大小是否会影响引用现有数组元素的指针?

谢谢,

[编辑]错误的假设被删除了。 (新数组元素初始化为0)

2 个答案:

答案 0 :(得分:10)

  • 现有数组元素将保持不变:
  • 新数组元素初始化为0:(请参阅更新) ,除非它是一个编译器管理类型数组,如字符串,另一个数组或变体
  • 所有数组元素在内存中都是连续的:

当阵列大小增加时,阵列将复制。来自doc: ...为数组赋值或将其传递给SetLength过程时,将重新分配动态数组的内存。

所以,增加动态数组的大小会对引用现有数组元素的指针产生影响

如果要保留对现有元素的引用,请在数组中使用它们的索引(从0开始)。

<强>更新

Rob和David的评论促使我检查了Delphi5中动态数组的初始化(因为我还是可以随时使用)。首先使用一些代码创建各种类型的动态数组并在调试器中检查它们。它们都已正确初始化,但这可能仍然是在分配它们的内存位置初始化之前的结果。所以检查了RTL。事实证明,D5已经在Rob指出的DynArraySetLength方法中有了FillChar语句:

  // Set the new memory to all zero bits
  FillChar((PChar(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0);

答案 1 :(得分:2)

在实践中,Embarcadero总是会初始化新元素,因为否则会破坏这么多代码。

事实上,他们没有正式保证零分配是一种耻辱,因为它非常有用。重点是,在编写SetLength时,通常在调用站点,您不知道您是在增长还是缩小阵列。但SetLength的实现确实知道 - 显然它必须。因此,对任何新元素进行明确定义的操作确实很有意义。

更重要的是,如果他们希望人们能够在托管世界和本地世界之间轻松切换,那么零分配是可取的,因为这适合托管代码。