[C/C++] sizeof struct
Résolu
KX
Messages postés
16761
Date d'inscription
Statut
Modérateur
Dernière intervention
-
Char Snipeur Messages postés 9813 Date d'inscription Statut Contributeur Dernière intervention -
Char Snipeur Messages postés 9813 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour,
Je viens de remarquer quelques choses qui me surprend, mais peut-être pourra-t-on m'expliquer.
Je pensais que la sizeof d'un struct était égal à la somme des sizeof des champs de la struct.
Voici ce que j'obtient (en commentaire le résultat de sizeof)
Comment se fait-il que l'on ait 1+4=8, et non pas 5 ?
Je viens de remarquer quelques choses qui me surprend, mais peut-être pourra-t-on m'expliquer.
Je pensais que la sizeof d'un struct était égal à la somme des sizeof des champs de la struct.
Voici ce que j'obtient (en commentaire le résultat de sizeof)
char // 1 int // 4 struct s1 { char c; }; // 1 struct s2 { int n; }; // 4 struct s3 { int n; char c; }; // 8 !!!
Comment se fait-il que l'on ait 1+4=8, et non pas 5 ?
2 réponses
Je ne suis pas sûr mais je pense que la structure a été paddée jusqu'à obtenir un multiple de 4.
Tu as essayé avec une structure contenant 1 int + 2,3 ou 4 char pour voir la valeur de sizeof ?
Tu as essayé avec une structure contenant 1 int + 2,3 ou 4 char pour voir la valeur de sizeof ?
Bonjour,
juste pour ajouter ma petite touche, pour avoir eu des problèmes avec les alignements (C++ + fortran77).
En effet, le compilateur se réserve le droit d'aligner comme il le souhaite les variables dans une structure. Cet alignement est propre au compilateur et à son implémentation. Même s'il se dégage une méthode générale (alignement à 8), tout comme le byte groupe 8 octet : ce n'est pas une obligation.
Dans gcc il existe des commandes pour maitriser l'alignement des structure avec __atribute__ http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes
Comme l'a dit supernico, au travail, nous mettons dans nos structures les plus gros éléments en premier et les plus petits en dernier. Cette simple méthode permet d'éviter en grande partie les problèmes d'alignements.
juste pour ajouter ma petite touche, pour avoir eu des problèmes avec les alignements (C++ + fortran77).
En effet, le compilateur se réserve le droit d'aligner comme il le souhaite les variables dans une structure. Cet alignement est propre au compilateur et à son implémentation. Même s'il se dégage une méthode générale (alignement à 8), tout comme le byte groupe 8 octet : ce n'est pas une obligation.
Dans gcc il existe des commandes pour maitriser l'alignement des structure avec __atribute__ http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html#Variable-Attributes
Comme l'a dit supernico, au travail, nous mettons dans nos structures les plus gros éléments en premier et les plus petits en dernier. Cette simple méthode permet d'éviter en grande partie les problèmes d'alignements.
Cependant, il est possible d'avoir des valeurs intermédiaires, avec 5 char par exemple on a bien 5... alors je ne comprends pas pourquoi parfois c'est exact, et parfois non.
par contre dès qu'il y a des int dans la structure c'est paddé.
Le but est surtout de garder l'alignement mémoire pour que les int pointent sur des blocs mémoire de 32 bits continus
Par exemple il est déconseillé de faire ça :
car tu pourrais avoir des problèmes avec le dernier int (sauf si ton compilateur est intelligent, auquel cas il allouera 12 octets au lieu de 10 comme prévu.
Il vaut mieux directement faire ça :
ou ça :
Sur un exemple simple comme ça, c'est facile à "optimiser", mais si ils sont imbriqués comme ceci
struct s1 { int a; char b; }; et struct s2 { struct s1 x,y; }; ce qui revient au même, l'optimisation est nettement moins évidente, et ça commence à faire pas mal de perte de mémoire !
Bon on va dire que le problème est résolu ;-)
la meilleure façon pour perdre un minimum de mémoire est de regrouper les int en début de chaque structure (ou tous les gros blocs qui ont besoin de 4 octets en général) puis les short (2 octets) puis les char (1 octet, les miettes ^^)