Si tratta dell'allineamento della memoria. Nel codice seguente, mi aspettavo che l'offset di b all'interno della struttura fosse 8 (macchina a 32 bit). Vedi here. Qui, rendendo b
si verificano sempre all'interno di una linea della cache. Tuttavia, non è questo il caso. Il membro b
in un oggetto globale di struct test1
sembra essere allineato. Non sono sicuro che il suo caso o compilatore lo faccia deliberatamente.Perché un membro doppio nella struttura non è allineato al limite di 8 byte?
Volevo capire perché il compilatore non riempie 4 byte dopo a
.
struct test1
{
int a;
double b;
}t1;
int main()
{
struct test1 *p = malloc(sizeof(struct test1));
printf("sizes int %d, float %d, double %d, long double %d\n", sizeof(int), sizeof(float), sizeof(double), sizeof(long double));
printf("offset of b %d\n",(int)&(t1.b)-(int)&(t1));
printf("\naddress of b (on heap) = %p, addr of b (on data seg) = %p\n",&(p->b), &(t1.b));
return 0;
}
L'uscita è ...
sizes int 4, float 4, double 8, long double 12
offset of b 4
address of b (on heap) = 0x804a07c, addr of b (on data seg) = 0x80497e0
Sto usando il compilatore gcc di serie su Ubuntu 10.04
Per prima cosa, se la CPU può trattare con operandi non allineati, non c'è nessun problema . Ora, il motivo per cui il compilatore è strettamente imballato strutture, è una domanda. Come stai compilando il codice?Ci sono delle opzioni di compilazione nascoste provenienti dai makefile o da qualunque cosa il compilatore potrebbe estrarre dai suoi file di configurazione? –
@Alexey, no, è solo gcc test.c; ./a.out – Chethan
Ottengo gli stessi risultati durante la compilazione con gcc 4.6.3 utilizzando le opzioni "predefinite" e -m32 (Ho un sistema operativo a 64-bit, quindi l'impostazione predefinita è 64-bit, e in quel caso, mi dà un allineamento di 8 byte). –