Domanda

Voglio prendere alcuni campi da pacchetto struct usando puntatore arithmetic.But ciò che è sbagliato con il codice qui sotto?
In prima condizione penso che se vado a 4 byte (2 brevi campo) dall'inizio del pacchetto ottengo tlow .Ma non dà previsto secondo caso value.Additionally voglio ottenere campo dati andando 12 byte dall'inizio del pacchetto .Che c'è di sbagliato con la mia idea?

struct packet{  
      short len;
      short field;
      int tLow;
      int tHigh;
      void *data;
}

int main()
{
    struct packet pack;
    struct packet *pck;

    pack.len=3;
    pack.field=34;
    pack.tLow=712;
    pack.tHigh = 12903;
    pack.data = "message";

    pck = &pack;
    int *timeLow = (int * )pck + 4; // i want to get tLow 
    printf("Time Low :%d\n",*time);

    char *msg = (char *)pck + 12 ;// want data 
    printf("Message :%s\n",msg);

    return 0;
}
È stato utile?

Soluzione

È sicuramente sarebbe meglio utilizzare metodo standard

int *timeLow = &(pck->tLow);

compilatori è consentito inserire byte di riempimento tra qualsiasi membro di una struttura. Le regole per questi byte di riempimento sono, nella migliore delle ipotesi, l'implementazione definito ... quindi è necessario consultare il manuale di implementazione per essere certi di come (o se) e quanti byte sono inseriti nel vostro caso specifico. Da notare anche il numero di byte di riempimento potrebbe cambiare dalla compilazione alla compilazione con diverse opzioni o dal compilatore di compilatore (da computer a computer, ...)

Si può provare a utilizzare il C macro offsetof, ma non è abbastanza:

size_t offset = offsetof(struct packet, tLow);
/* make sure offset is a multiple of sizeof (int*) */
int *timeLow = (int*)pck + offset / sizeof (int*);

o, un po 'meno brutto con un cast di (char*) e copiare il codice da altre risposte : -)

size_t offset = offsetof(struct packet, tLow);
int *timeLow = (int*)((char*)pck + offset);

Oh! e c'è un punto e virgola mancante nella vostra fonte

Altri suggerimenti

In pratica si fa affidamento su un comportamento indefinito. allineamento Struct, ecc, ma in ogni modo ...

(int *) PCK + 4. avanzerà il puntatore 4 * sizeof (int). Questo è sbagliato, noi vogliamo avanzare di 1 se si assume che la struct è imballato e sizeof (breve) == 2, quindi ...

int *timeLow = (int * )pck + 1; // i want to get tLow 
printf("Time Low :%d\n",*timeLow);

stampa il risultato corretto.

Per quanto riguarda il messaggio, è necessario fare alcune cose sporche. Dal momento che sono in x86_64 il compilatore ha scelto di riempire il vuoto * su 8 limiti di byte, quindi l'offset è stato 16 anziché il previsto 12.

Siamo fondamentalmente il recupero di un puntatore ad un * vuoto. Così il codice sarà simile a questa:

char **msg = (char**)((char *)pck + 16) ;// want data 
printf("Message :%s\n",*msg);

NON scrivere il codice come questo, questo solo illustra un punto.

Siete alla ricerca di offsetof .

Il codice potrebbe essere simile a questo:

int *timeLow = (int*) ((char*)pck + offsetof(struct packet, tLow);

e come PMG ha sottolineato,

int *timeLow = &(pck->tLow);

è il modo canonico di ottenere un puntatore a un membro di una struct.

Questa risposta ha portato anche puntatore aritmetica sul tavolo -. ho imparato che oggi grazie alla PMG

quando si scrive

int *timeLow = (int * )pck + 4

si sta trattando 'PCK' come un puntatore int, che a seconda del sistema può essere 4 o 8 byte. Che non compensato correttamente nel struct perché si sta quindi dicendo che per avere un offset di 4 int

invece si avrebbe bisogno di fare come questo

int *timeLow = (int*)((short * )pck + 2); 

bicchierini non sono necessariamente 2 byte. Tutto specificato è che sono meno di o uguale alla dimensione di int. Probabilmente si dovrebbe utilizzare sizeof ()

Questo è sbagliato: pack.data = "message"; Si sta utilizzando la memoria non allocato.

Anche questo: int *timeLow = (int * )pck + 4; non è garantito il funzionamento (allineamento struct varia tra compilatori e sistemi).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top