Comment sizeof calcule la taille des structures
Je sais qu'un char et int sont calculés comme étant de 8 octets sur les architectures 32 bit en raison de l'alignement, mais je suis récemment tombé sur une situation où une structure avec 3 courts métrages a été signalé comme étant de 6 octets par l'opérateur sizeof. Le Code est comme suit:
#include <iostream>
using namespace std ;
struct IntAndChar
{
int a ;
unsigned char b ;
};
struct ThreeShorts
{
unsigned short a ;
unsigned short b ;
unsigned short c ;
};
int main()
{
cout<<sizeof(IntAndChar)<<endl; //outputs '8'
cout<<sizeof(ThreeShorts)<<endl; //outputs '6', I expected this to be '8'
return 0 ;
}
Compilateur g++ (Debian 4.3.2-1.1) 4.3.2. Cela m'étonne vraiment, c', pourquoi n'est-ce pas l'alignement appliquée pour la structure contenant 3 courts métrages?
source d'informationauteur Gearoid Murphy
Vous devez vous connecter pour publier un commentaire.
C'est parce que
int
est de 4 octets, et doit être aligné sur 4 octets limite. Cela signifie que TOUTEstruct
contenant unint
doit également être aligné au moins 4 octets.D'autre part,
short
est de 2 octets, et les besoins de l'alignement seulement 2 octets limite. Si unstruct
contenantshort
s ne contient pas tout ce qui a besoin d'un plus grand alignement, lastruct
sera également aligné sur 2 octets.Ce que l'alignement voulez-vous avoir ?
Shorts peut être alignés sur 2 octets limites sans les mauvais effets(en supposant commune x86 compilateurs tous ici..). Donc, si vous créez un tableau de
struct ThreeeShorts
, cette structure ayant une taille de 6 est très bien, comme tous les éléments dans une matrice de commencer sur une frontière d'octet 2.Votre
struct IntAndChar
contient un int, ints veut 4 octets de l'alignement, donc si vous créez un tableau destruct IntAndChar
la taille doivent être 8 pour le prochain élément à être alignée sur une frontière d'octet 4.Si nous ne considérons pas les tableaux, il ne serait pas beaucoup d'importance si
struct IntAndChar
étaient de 5 octets de long, le compilateur aurait juste allouer un départ le 4 octets à la frontière, quand vous créez un un la pile, ou l'utiliser comme un composé membre dans une autre structure.Vous pouvez toujours obtenir le nombre d'éléments dans un tableau en faisant sizeof(arrayofT)/sizeof(T), et les éléments du tableau sont garantis pour être stockées adjacente, tels que le n-ième élément peut être récupéré par une intensification de la N*sizeof(arrayelementtype) octets depuis le début, et c'est la raison principale pour laquelle vous verrez des structs être rembourré à la fin.
Je ne sais pas d'où vous est venue l'idée sur
char
ouint
être calculée comme étant "8 octets". Non, chaque type est calculé conformément à sa taille:char
1,int
que 4 sur une plate-forme 32 bits (pas 8, mais 4). L'alignement exigence pour chaque type est normalement le même que sa taille (même si il n'a pas à être).Pour cette raison, lorsque la structure contient les membres de la même type, la taille totale de cette structure sera normalement la somme des tailles de ses membres: une structure de 3
char
s auront taille 3, et la structure de deuxint
s auront taille 8.Apparemment de type
short
sur votre plate-forme de taille a 2, donc, évidemment, d'une structure de 3 courts métrages a une taille de 6, ce qui est exactement ce que vous observez.Toutefois, lorsque votre structure contient des membres de la différents types, alors la différence entre les exigences alignement de différents types entre en jeu. Si l'alignement exigence de la prochaine terrain est plus stricte que celle de l'alignement de l'exigence du champ précédent, le compilateur peut avoir à ajouter des octets de remplissage entre ces deux champs (pour aligner correctement le membre suivant), qui aura une incidence sur la taille finale de la struct. En outre, le compilateur pourrait avoir à ajouter un peu de rembourrage supplémentaire octets après le dernier membre de la structure pour satisfaire les exigences alignement dans un tableau.
Par exemple, une structure qui se présente comme suit
sera très probablement occupent des 8 octets sur votre plate-forme en raison de la nécessité pour les 3 octets de remplissage après la
char
membre. Remarque,char
compte comme 1,int
que le 4 et le 3 octets de remplissage entre les 8.Note également que cette situation peut facilement introduire la dépendance de la taille finale de la structure sur l'ordre dans lequel les membres sont déclarées. Par exemple, cette structure
sur votre plate-forme aura probablement de taille 12, tandis que celui-ci
occupera uniquement de 8 octets. Ce dernier exemple est destiné à illustrer le fait que le final de la taille de la structure ne peut pas être exprimé en terme de nombre d'octets de chaque membre "compte". Les relations entre les membres sont également importants.
Il est entièrement dépendant de l'implémentation, mais on peut supposer que si votre système peut accéder à toutes les trois
short
s dans la structure sans se soucier de l'alignement, il peut accéder à tousshort
et que par conséquent, le membre de données dans un tableau deThreeShorts
sans se soucier de l'alignement. Par conséquent, il n'est pas nécessaire d'aligner les structures de manière plus stricte.Pour la
IntAndChar
exemple,int
a sans doute de taille 4 et de la mise en œuvre est son alignement. Pour s'assurer que tous lesint
membre dans un tableau deIntAndChar
est correctement aligné, la structure doit être rembourré.La
sizeof
un tableauT[n]
est exactement définie commesizeof(T) * n
.Ce lien devrait vous aider: http://en.wikipedia.org/wiki/Data_structure_alignment
Dans
ThreeShorts
tous les membres sont de deux octets alignés.Yep, j'ai eu le même problème. J'ai la structure suivante
Cela me donne ::8:2:4 ?? pourquoi le montant total de la structure = 8, mais les éléments individuels ne pas faire la somme??
C'est en raison de l'alignement de mémoire, la mémoire est rembourré avec supplément de 2 octets pour l'alignement.
Grâce