How does MemoryLayout calculate size for a struct ?
I read this article, and I seemed to understand it pretty well, until I got stuck on the following problem:
struct CertifiedPuppy1 {
let age: Int
let isTrained: Bool
let isCertified: Bool
}
MemoryLayout<CertifiedPuppy1>.size // 10
MemoryLayout<CertifiedPuppy1>.stride // 16
MemoryLayout<CertifiedPuppy1>.alignment // 8
struct CertifiedPuppy2 {
let isTrained: Bool
let age: Int
let isCertified: Bool
}
MemoryLayout<CertifiedPuppy2>.size // 17
MemoryLayout<CertifiedPuppy2>.stride // 24
MemoryLayout<CertifiedPuppy2>.alignment // 8
struct CertifiedPuppy3 {
let isTrained: Bool
let isCertified: Bool
let age: Int
}
MemoryLayout<CertifiedPuppy3>.size // 16 <--why not 10, like for CertifiedPuppy1 ??--
MemoryLayout<CertifiedPuppy3>.stride // 16
MemoryLayout<CertifiedPuppy3>.alignment // 8
Question is, why does CertifiedPuppy3
have size 16, instead of 10, like for CertifiedPuppy1
?
As I understand it, pretty much there is one main rule:
Image below shows the layouts of bytes for your examples.
Lets see your last example - CertifiedPuppy3:
- alignment for isTrained (Bool) is 1, that means it can start at any address, so it starts at 0.
- alignment for isCertified (Bool) is also 1, so there is no problem for isCertified to start at 1.
- alignment for age (Int) is 8, so it can start only on 0, 8, 16, 24... That is why start address of age is at 8, and not at 2. If it was at 2 it would be misaligned.
So CertifiedPuppy3 has size of 16 because its properties must follow alignment rules.
Non-related to question, there is also this:
That is why stride for CertifiedPuppy2 is 24: alignment for CertifiedPuppy2 is 8, since its size is is 17 next available position for start of new CertifiedPuppy2 object is at 24 - that is what stride is - minimum distance between two CertifiedPuppy2 objects.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With