MemoryLayout in Swift
Asked Answered
J

1

6

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 ?

Juni answered 16/3, 2018 at 21:33 Comment(3)
Each Int is aligned to a 8-byte boundary and has size 8.Alcheringa
Possibly helpful: #47611495.Alcheringa
Ahh, you mean CertifiedPuppy1: 8 + 1 + 1 + (buffer 6, ignored) = 10; CertifiedPuppy3: 1 + 1 + (buffer 6, counted) + 8 = 16Juni
R
5

As I understand it, pretty much there is one main rule:

  • start address of every object must be at a multiple of its alignment. That rule is applied for everything - properties in a struct (Int, Bool, etc.), struct itself, and all other types.

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:

  • alignment of a struct is equal to maximum alignment of its properties.

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.

alignment

Rubinrubina answered 5/12, 2018 at 23:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.