我想了解当动态数组的大小增加时会发生什么。
到目前为止我的理解:
当数组大小增加时,是将额外的内存添加到现有内存块上,还是将现有元素复制到一个全新的内存块?
更改动态数组的大小是否会影响引用现有数组元素的指针?
谢谢,
[编辑]错误的假设被删除了。 (新数组元素初始化为0)
答案 0 :(得分:10)
当阵列大小增加时,阵列将复制。来自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的实现确实知道 - 显然它必须。因此,对任何新元素进行明确定义的操作确实很有意义。
更重要的是,如果他们希望人们能够在托管世界和本地世界之间轻松切换,那么零分配是可取的,因为这适合托管代码。