La maggior parte dei compilatori allinea automaticamente i valori dei dati alla dimensione della parola della piattaforma o alle dimensioni del tipo di dati, a seconda di quale di esse sia più piccola. La stragrande maggioranza dei processori consumer e aziendali utilizza una dimensione word di 32 bit. (Anche i sistemi a 64 bit usano solitamente 32 bit come dimensione nativa di una parola)
Come tale, l'ordinamento dei membri nella tua struttura potrebbe sprecare un po 'di memoria. Nel tuo caso specifico, stai bene. Aggiungerò nei commenti l'impronta reale di memoria utilizzata:
typedef struct structc_tag{
char c; // 1 byte
// 3 bytes (padding)
double d; // 8 bytes
int s; // 4 bytes
} structc_t; // total: 16 bytes
Questa regola si applica alle strutture troppo, quindi, anche se li riorganizzate in modo che il campo più piccolo era ultima, si avrebbe ancora una struttura delle stesse dimensioni (16 byte).
typedef struct structc_tag{
double d; // 8 bytes
int s; // 4 bytes
char c; // 1 byte
// 3 bytes (padding)
} structc_t; // total: 16 bytes
Se si dovesse dichiarare più campi che erano più piccola di 4 byte, si poteva vedere alcune riduzioni di memoria se li raggruppate in base alle dimensioni. Per esempio:
typedef struct structc_tag{
double d1; // 8 bytes
double d2; // 8 bytes
double d3; // 8 bytes
int s1; // 4 bytes
int s2; // 4 bytes
int s3; // 4 bytes
short s4; // 2 bytes
short s5; // 2 bytes
short s6; // 2 bytes
char c1; // 1 byte
char c2; // 1 byte
char c3; // 1 byte
// 3 bytes (padding)
} structc_t; // total: 48 bytes
Dichiarazione di una struct stupido potrebbe perdere un sacco di memoria, a meno che il compilatore riordina gli elementi (che, in generale, non sarà così, senza essere esplicitamente detto di)
typedef struct structc_tag{
int s1; // 4 bytes
char c1; // 1 byte
// 3 bytes (padding)
int s2; // 4 bytes
char c2; // 1 byte
// 3 bytes (padding)
int s3; // 4 bytes
char c3; // 1 byte
// 3 bytes (padding)
} structc_t; // total: 24 bytes
// (9 bytes wasted, or 38%)
// (optimal size: 16 bytes (1 byte wasted))
Le doppie sono più grandi di 32 bit e, pertanto, secondo la regola della prima sezione, sono allineate a 32 bit. Qualcuno ha menzionato un'opzione del compilatore che modifica l'allineamento e che l'opzione del compilatore di default è diversa tra i sistemi a 32 e 64 bit, anche questo è valido. Quindi la vera risposta al doppio è che dipende dalla piattaforma e dal compilatore.
Le prestazioni della memoria sono regolate da parole: il caricamento dalla memoria avviene in fasi che dipendono dal posizionamento dei dati. Se i dati coprono una parola (i.e. è allineata alla parola), solo quella parola deve essere caricata. Se non è allineato correttamente (cioè un int a 0x2), il processore deve caricare 2 parole per leggere correttamente il suo valore. Lo stesso vale per i doppi, che normalmente occupano 2 parole, ma se disallineati, occupano 3. Nei sistemi a 64 bit in cui è possibile il caricamento nativo di quantità a 64 bit, si comportano come 32 bit inte su sistemi a 32 bit in quanto se allineati correttamente , possono essere recuperati con un carico, ma per il resto, richiederanno 2.
L'allineamento è definito dall'implementazione, quindi non ha molto senso fare questa domanda in modo così generale. Dovresti scegliere un compilatore/piattaforma specifico per informazioni. –
In realtà ottengo 24 byte ... –
C'è anche un riempimento di 4 byte all'estremità per garantire che il doppio sia ancora allineato negli elementi di una matrice di queste strutture. Generalmente. –