Программисты используют структуры, в конце которых расположен массив переменного размера. Эта структура и выделение памяти для неё может выглядеть следующим образом:Код
Type MyPointersArray
Length As Long
Vector(0) As Any Ptr
End Type
Dim WrongSize As UInteger = SizeOf(Long) + 5 * SizeOf(Any Ptr)
Dim p As MyPointersArray Ptr = Allocate(WrongSize)
Этот код будет корректно работать в 32-битном варианте, однако его 64-битный вариант покажет крах. При выделении памяти, необходимой для хранения объекта типа `MyPointersArray`, содержащего 5 указателей, необходимо учесть, что начало массива `Vector` будет выровнено по границе 8 байт. Расположение данных в памяти на разных системах (Win32/Win64) выглядит так.
Для 32‐бит:
Код
Length
Vector(0)
Vector(1)
Vector(2)
Vector(3)
Vector(4)
Для 64‐бит:
Код
Length
alignment <--- выравнивание
Vector(0)
Vector(1)
Vector(2)
Vector(3)
Vector(4)
Правильный расчёт размера должен выглядеть следующим образом:
Код
Dim RealSize As UInteger = OffsetOf(MyPointersArray, Vector(0)) + 5 * SizeOf(Any Ptr)
В приведённом коде мы узнаём смещение последнего члена структуры и суммируем это смещение с его размером. Смещение члена структуры или класса можно узнать с использованием макроса `OffsetOf`. Всегда используйте макрос `OffsetOf` для получения смещения в структуре, не опираясь на свои предположения о размерах типов и правилах их выравнивания.