0Pricing
Swift Academy · Leçon

MemoryLayout et alignement

Inspectez la taille, le pas et l’alignement des types.

MemoryLayout et alignement est une leçon Swift Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Swift Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Swift Academy comprend 4 leçons au total.

Pourquoi la disposition de la mémoire est importante

Lorsque vous travaillez avec Swift non sécurisé ou que vous l'interconnectez avec C, vous devez savoir comment les valeurs sont disposées en mémoire. Swift vous fournit MemoryLayout<T> pour examiner cette disposition sans jamais manipuler directement des octets bruts.

Cela répond à trois questions : quelle est la taille d'une valeur, quelle est la distance entre les valeurs d'un tableau et sur quelle limite d'adresse une valeur doit commencer.

// MemoryLayout works on any type
print(MemoryLayout<Int>.size)       // 8 on 64-bit
print(MemoryLayout<Bool>.size)      // 1
print(MemoryLayout<Double>.size)    // 8

size — Stockage réel

MemoryLayout<T>.size correspond au nombre d'octets occupés par les données significatives de la valeur. Il n'inclut pas le remplissage final qui peut se trouver entre les éléments d'un tableau.

Utilisez size lorsque vous voulez savoir combien d'octets significatifs contient une seule valeur.

struct Point {
    var x: Int8   // 1 byte
    var y: Int64  // 8 bytes
}

print(MemoryLayout<Point>.size)   // 16 (not 9 — padding!)

stride — Espacement dans les tableaux

stride est la distance en octets entre le début d'un élément et celui du suivant lorsque les valeurs sont stockées dans un tableau contigu. Il correspond à size arrondi à la valeur d'alignment.

Lorsque vous allouez manuellement des tampons, multipliez par stride, jamais par size.

print(MemoryLayout<Point>.stride) // 16
print(MemoryLayout<Int8>.stride)  // 1

// Buffer for 10 Points needs:
let bytes = 10 * MemoryLayout<Point>.stride // 160

alignment — Limites d'adresse

alignment est la limite en octets sur laquelle une valeur doit commencer. Un entier sur 64 bits dont l'alignement est de 8 doit commencer à une adresse divisible par 8. Le compilateur ajoute du remplissage pour respecter cette contrainte.

L'alignement d'une structure est l'alignment le plus élevé parmi ses membres.

print(MemoryLayout<Int8>.alignment)   // 1
print(MemoryLayout<Int64>.alignment)  // 8
print(MemoryLayout<Point>.alignment)  // 8

La différence entre size et stride

Pour de nombreux types, size == stride, mais ces valeurs diffèrent dès qu'il y a du remplissage. Une structure peut avoir une size de 9 et un stride de 16, car l'élément suivant doit être aligné sur 8 octets.

Règle générale : utilisez size pour raisonner sur une seule valeur et stride pour raisonner sur des collections.

struct Mixed {
    var flag: Bool   // 1
    var value: Int   // 8
}
print(MemoryLayout<Mixed>.size)   // 16
print(MemoryLayout<Mixed>.stride) // 16

Décalages des champs

Pour les structures, vous pouvez déterminer où se trouve chaque propriété stockée par rapport au début en utilisant MemoryLayout<T>.offset(of:) avec un chemin clé. C'est essentiel lorsque vous disposez les données pour correspondre à une structure C.

struct Header {
    var magic: UInt32  // offset 0
    var length: UInt64 // offset 8 (padded)
}

print(MemoryLayout<Header>.offset(of: \Header.magic) ?? -1)  // 0
print(MemoryLayout<Header>.offset(of: \Header.length) ?? -1) // 8

Réorganiser pour économiser de l'espace

En raison de l'alignement, l'ordre des propriétés stockées influe sur la taille. Placer les champs les plus grands en premier ou les regrouper par taille peut réduire une structure. Cela est important pour les grands tableaux, où les octets inutilisés finissent par s'accumuler.

struct Wasteful { var a: Int8; var b: Int64; var c: Int8 } // size 24
struct Tight    { var b: Int64; var a: Int8; var c: Int8 } // size 16

print(MemoryLayout<Wasteful>.size)
print(MemoryLayout<Tight>.size)

Disposition des références

Une instance de classe est allouée dans le tas : une variable contenant une référence de classe n'est donc qu'un pointeur. Sa valeur MemoryLayout.size correspond à la taille du pointeur (8 octets), quelle que soit la taille de l'objet.

Les types valeur, comme les structures, stockent leur contenu directement ; les types référence ne stockent que le pointeur.

class Big { var data = [Int](repeating: 0, count: 1000) }

print(MemoryLayout<Big>.size) // 8 — just the reference

Types optionnels et énumérations

Les types optionnels ajoutent généralement un octet pour l'étiquette, mais Swift optimise les types optionnels de référence en réutilisant le pointeur nul. Ainsi, String? peut avoir la même taille que String.

Les énumérations avec valeurs associées sont dimensionnées pour contenir leur cas le plus volumineux ainsi qu'un discriminant.

print(MemoryLayout<Int?>.size)    // 9
print(MemoryLayout<String>.size)  // 16
print(MemoryLayout<String?>.size) // 16 — no extra byte

Utiliser la forme basée sur une instance

Chaque membre (size, stride, alignment) possède aussi une forme basée sur une instance : MemoryLayout.size(ofValue:). Cela est pratique lorsque le type est difficile à écrire explicitement ou qu'il est déduit.

let tuple = (UInt8(1), UInt64(2))
print(MemoryLayout.size(ofValue: tuple))      // 16
print(MemoryLayout.stride(ofValue: tuple))    // 16
print(MemoryLayout.alignment(ofValue: tuple)) // 8

Allouer avec la disposition correcte

Lorsque vous allouez de la mémoire brute, vous devez fournir à la fois le nombre d'octets et l'alignement. Les obtenir depuis MemoryLayout garantit la correction sur toutes les architectures, plutôt que de coder des nombres en dur.

let count = 4
let capacity = count * MemoryLayout<Int>.stride
let align = MemoryLayout<Int>.alignment

let raw = UnsafeMutableRawPointer.allocate(
    byteCount: capacity, alignment: align)
defer { raw.deallocate() }

Vérification rapide

Vérifiez votre compréhension de la différence entre size et stride.

Récapitulatif

Vous avez découvert les trois piliers de la disposition de la mémoire :

  • size — octets significatifs d'une seule valeur
  • stride — espacement entre les éléments d'un tableau (à utiliser pour l'allocation)
  • alignment — limite de début requise

Vous avez également vu offset(of:) pour les positions des champs, l'influence de l'ordre des propriétés sur la taille, ainsi que le fait que les références ont simplement la taille d'un pointeur. Ces outils vous permettent d'allouer et d'interpréter la mémoire brute en toute sécurité.

Questions Fréquemment Posées

La leçon « MemoryLayout et alignement » est-elle gratuite ?

Oui — le texte complet de « MemoryLayout et alignement » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Swift Academy, passe à CoddyKit PRO. Le cours Swift Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « MemoryLayout et alignement » ?

Inspectez la taille, le pas et l’alignement des types. Tu pratiques Swift Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Swift Academy ?

Aucune expérience préalable n'est requise. Swift Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « MemoryLayout et alignement » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Swift Academy ?

Oui. Chaque leçon Swift Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. MemoryLayout et alignement
  2. UnsafePointer et UnsafeMutablePointer
  3. Pointeurs de tampons non sûrs
  4. withUnsafeBytes et interopérabilité C
← Retour à Swift Academy