How to get the memory size of a dynamic array?
在Delphi中,您可以使用sizeof()编译器魔术函数获得值类型的大小,但是在引用类型上调用sizeof()则将为您提供指针的大小,而不是指针所指向的值。
对于对象,可以使用InstanceSize方法获取内存大小,但是对于动态数组呢?由于填充原因,length(MyArray) * sizeof(element)可能不准确。那么,有什么准确的方法来获取动态数组的内存大小?
- 自从我在Delphi中进行指针计算以来已经有一段时间了,但是呢:PChar(@MyArray[last+1]) - PChar(@MyArray[0])呢?当然,last + 1可能会导致索引超出范围异常,因此您可能要使用last代替,并计算每个元素的实际大小(填充和全部)并将其添加到其中。
-
我不确定在Borland编译器的世界中是否存在任何数组元素填充。
-
没有填充。您可以使用Length(MyArray) * SizeOf(Element)。
-
数组元素之间没有填充,但是数组元素前面有隐藏的数据来保存数组的引用计数等。因此Length(MyArray) * SizeOf(ElementType)会告诉您分配了多少字节来保存数组的元素数据,但不会告诉您为整个动态数组整体分配了多少字节。
-
但是我怀疑产品的长度*大小仍然是梅森所追求的,不是吗?
-
所有的Delphi数组都已打包。如果数组元素本身是数组或其他一些非值类型,该怎么办?
-
出于可移植性的原因,我会采用Lasse的指针数学方法。
-
@Remy,对象也具有簿记内存,但是如果InstanceSize足以提供对象的内存大小,则长度乘以元素大小应足够用于数组。
实际上,length(MyArray) * sizeof(element)对于数组内容是准确的,但不包括任何内部动态数组或字符串。
如果要整个数组使用内存,包括嵌套引用类型的内容大小,则可以使用我们的TDynArraypackage器。它能够将任何动态数组(包括引用计数的成员(如动态数组或字符串))序列化为二进制。为此,您具有SaveTo / SaveToStream方法,并且能够获取所有内容的实际大小。
看一下这篇博客文章,其中介绍了该package。它是开放源代码,在Win32和Win64平台上均可从Delphi 5到XE4进行工作。
动态数组的元素之间没有填充,Length(MyArray)*SizeOf(Element)应该准确。