Here is a simple example:
struct Foo {
let a: Int16
let b: Int8
}
print(MemoryLayout<Foo>.size) // 3
print(MemoryLayout<Foo>.alignment) // 2
print(MemoryLayout<Foo>.stride) // 4
- The alignment of the struct is the maximal alignment of all its
fields, in this case the maximum of
2
and 1
.
- The stride of the struct is the size rounded up to alignment,
here
3
rounded up to a multiple of 4
.
The stride is the distance between (the start of) contiguous instance of the same type in memory:
let array = [Foo(a: 1, b:2), Foo(a: 3, b: 4), Foo(a: 5, b: 6)]
array.withUnsafeBytes {
print(Data($0) as NSData) // <01000234 03000474 0500066f>
print($0.count) // 12
}
The struct stride is a multiple of the struct alignment, so that
all instances (and therefore all instance fields) are properly aligned.
The details can be found in
Type Layout:
Fragile Struct and Tuple Layout
Structs and tuples currently share the same layout algorithm, noted as the "Universal" layout algorithm in the compiler implementation. The algorithm is as follows:
- Start with a size of 0 and an alignment of 1.
- Iterate through the
fields, in element order for tuples, or in var declaration order for
structs. For each field:
- Update size by rounding up to the alignment
of the field, that is, increasing it to the least value greater or
equal to size and evenly divisible by the alignment of the field.
- Assign the offset of the field to the current value of size.
- Update
size by adding the size of the field.
- Update alignment to the max of
alignment and the alignment of the field.
- The final size and alignment
are the size and alignment of the aggregate. The stride of the type is
the final size rounded up to alignment.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…