2011-12-15 19 views
7

Ecco il codice in questioneC aritmetica dei puntatori sizeof (struct)

#include <stdio.h> 

struct test { 
    unsigned char t; 
    unsigned short u; 
    unsigned char v; 
}; 


int main() 
{ 
    struct test * a = (void *) 0x1000; 

    printf("%x %p %p\n", 
      sizeof(struct test), 
      a + sizeof(struct test), 
      a - sizeof(struct test)); 

    return 0; 
} 

Il sizeof (test struct) stampa 6, quindi vorrei aspetterebbe di vedere:

6 0xffa 0x1006

Invece ottengo

6 0x1024 0xfdc 

Ultima volta che c hecked, 0x24 o 36, non era uguale a 6. Non è nemmeno allineato a nulla che io possa dire. Sono a una perdita completa.

Qualcuno può spiegarmi perché sto ottenendo questi valori?

risposta

16

Il problema è che quando si esegue l'aritmetica del puntatore, aumenta di un più della dimensione del tipo di dati.

Quindi quello che stai facendo efficacemente è aggiungere dal quadrato di sizeof(struct test).

Dal sizeof(struct test) = 6, si sta incrementando l'indirizzo di 6 * 6 = 36. Quindi perché si ottiene 0x1024 e 0xfdc anziché 0x1006 e 0xffa. (È anche acceso il + e -, ma questa è una piccola cosa.)

Invece, basta fare questo:

printf("%x %p %p\n", 
     sizeof(struct test), 
     a + 1, 
     a - 1); 
1

Hai un puntatore digitato.

Quindi quando si incrementa il mio 1 (ad esempio a + 1) significa a + sizeof(type).

Così a + sizeof(type) = a + sizeof(type) * sizeof(type) = a + 6 * 6 (nel tuo caso come sizeof (test) = 6)

Ecco dove si stanno ottenendo 0x24 o 36 da.

2

Penso che si sta cercando a + 1 e a - 1.

(a + x) è lo stesso è &a[x].

+2

Probabilmente si vuole dire che '* (a + x)' è uguale a 'a [x]' o che '(a + x)' è uguale a '& a [x]'. –

4

Quando si esegue l'aritmetica del puntatore in questo modo, si sposta avanti o indietro di quel numero di elementi, come se quella variabile fosse in una matrice. Quindi vuoi veramente usare solo a + 1 e a - 1, che dovrebbe avanzare di 6 byte ogni volta.

IMPORTANTE: Tenere presente che il compilatore può aggiungere un riempimento nella struttura per facilitare l'allineamento. Non assumerlo solo perché hai due caratteri di un byte e un byte di due byte che la tua struttura avrà una dimensione di 4 byte --- questo non è il caso qui. (In realtà, non dare per scontato che tu conosca la dimensione di char o short, ho visto caratteri a 2 byte prima).

+3

In realtà non è abbastanza preciso.Non può aggiungere padding tra gli elementi dell'array. Ciò che può fare è eseguire il pad tra gli elementi di una struttura e dopo l'ultimo elemento di una struttura (questo è probabilmente il bit a cui ti riferisci). Ma la struttura stessa è riempita per essere la dimensione corretta se ha requisiti di allineamento - i sei byte qui sono probabilmente 'char (1), pad (1), short (2), char (1), pad (1)' ma quel padding finale appartiene ad un singolo elemento della struttura, non è _tra gli elementi in un array costituito da quella struttura. Modalità Nitpick disattivata :-) – paxdiablo

+1

Grazie, ho riformulato la mia risposta dopo aver esaminato le specifiche C99. –