8

In Delphi, you can get the size of a value type with the sizeof() compiler magic function, but calling sizeof() on a reference type will give you the size of a pointer, not of the value it's pointing to.

For objects, you can get the memory size with the InstanceSize method, but what about for dynamic arrays? Due to padding, length(MyArray) * sizeof(element) may not be accurate. So, is there any accurate way to get the memory size of a dynamic array?

Mason Wheeler
  • 82,511
  • 50
  • 270
  • 477
  • 1
    It's been a while since I did pointer calculations in Delphi, but what about this: `PChar(@MyArray[last+1]) - PChar(@MyArray[0])` ? Of course, `last + 1` might cause an index out of bounds exception, so you might want to use `last` instead and calculate the *real* size (padding and all) of each element and add that to it. – Lasse V. Karlsen Jul 11 '13 at 17:06
  • I'm not sure if there is any array element padding in Borland compilers' world. – OnTheFly Jul 11 '13 at 17:08
  • 3
    [There is no padding](http://stackoverflow.com/questions/4583985/are-there-any-difference-between-array-and-packed-array-in-delphi). You can use `Length(MyArray) * SizeOf(Element)`. – Ondrej Kelle Jul 11 '13 at 17:09
  • There is no padding between array elements, but there is hidden data in front of the array elements to hold the array's reference count and such. So `Length(MyArray) * SizeOf(ElementType)` will tell you how many bytes were allocated to hold the array's element data, but it will not tell you how many bytes were allocated for the entire dynamic array as a whole. – Remy Lebeau Jul 11 '13 at 17:53
  • 1
    But I suspect that the length*sizeof product still is what Mason is after, isn't it? – Andreas Rejbrand Jul 11 '13 at 18:24
  • All Delphi arrays are packed. What if the array element is itself an array, or some other non-value type? – David Heffernan Jul 11 '13 at 18:47
  • I'd go Lasse's pointer math way for the portability reasons. – OnTheFly Jul 11 '13 at 19:31
  • @Remy, objects have bookkeeping memory, too, but if `InstanceSize` is sufficient for giving the memory size of an object, then length times element size should be sufficient for arrays. – Rob Kennedy Jul 11 '13 at 20:50

2 Answers2

7

In fact, length(MyArray) * sizeof(element) will be accurate for the array content excluding any internal dynamic array or string.

If you want the whole array used memory, including nested reference types content size, you can use our TDynArray wrapper. It is able to serialize into binary any dynamic array, including reference counted members (like dynamic arrays or strings). You have SaveTo / SaveToStream methods for this purpose, and you are able to get the actual size of all content.

Take a look at this blog article, which presents this wrapper. It is open source, and works from Delphi 5 up to XE4, in both Win32 and Win64 platform.

Arnaud Bouchez
  • 42,305
  • 3
  • 71
  • 159
6

Between elements of a dynamic array there is no padding, Length(MyArray)*SizeOf(Element) should be accurate.

Stijn Sanders
  • 35,982
  • 11
  • 45
  • 67
  • If the element is also dynamic then SizeOf (Element) is also variable. Your formula is valid if each "Element" has the same size. – Petrus Jun 23 '22 at 07:29