struct ma_structure {
char champ1; /* 8 bits */
int champ2; /* 32 bits */
char champ3; /* 8 bits */
};
On pourrait penser que cette structure occupera 6 octets en mémoire, et pourtant, sur une bonne partie des
compilateurs, on obtiendrait une taille plus proche des 12 octets.
En fait, les compilateurs insèrent quasiment toujours des octets entre les champs pour pouvoir les aligner sur des
adresses qui correspondent à des mots machines. Cela est dû à une limitation de la plupart des processeurs, qui ne
peuvent lire des « mots » de plus d'un octet que s'ils sont alignés sur un certain adressage (alors qu'il n'y a pas de
contrainte particulière pour lire un seul octet, si le type char est défini sur 8bit).
En se représentant la mémoire comme un tableau continu, on peut tracer le dessin suivant:
| bloc N | bloc N + 1 | bloc N + 2 |
---+---------------+---------------+---------------+---
| a | b | c | d | e | f | g | h | i | j | k | l |
---+---------------+---------------+---------------+---
Les cases a, b, c, ... représentent des octets, et les blocs des sections de 32 bits. Si on suppose qu'une variable de type
ma_structure doive être placée en mémoire à partir du bloc numéro N, alors un compilateur pourra, pour des raisons
de performance, placer champ1 en a, champ2 de e à h, et champ3 en i. Cela permettrait en effet d'accéder
simplement à champ2: le processeur fournit des instructions permettant de lire ou d'écrire directement le bloc N + 1.
Dans ce cas, les octets de b à d ne sont pas utilisés; on dit alors que ce sont des octets de bourrage (ou padding en
anglais). Un autre compilateur (ou le même, appelé avec des options différentes) peut aussi placer champ2 de b à e,
et champ3 en f, pour optimiser l'utilisation mémoire. Mais alors il devra générer un code plus complexe lors des
accès à champ2, le matériel ne lui permettant pas d'accéder en une seule instruction aux 4 octets b à e.
En fait il faut garder à l'esprit que toutes les variables suivent cette contrainte: aussi bien les variables locales aux
fonctions, les champs de structures, les paramètres de fonctions, etc.
L'existence d'octets de bourrage ainsi que leur nombre sont non seulement dépendants de l'architecture, mais aussi du
compilateur. Cela dit, il est toujours possible de connaître la « distance » (offset) d'un champ par rapport au début de
la structure, et ce, de manière portable. Pour cela il existe une macro, déclarée dans l'entête <stddef.h>:
Partager