2016-05-20 16 views
6

Sto giocherellando con i puntatori in C e sono ancora incerto su alcune basi. Sono venuto con il seguente codice esemplare:C: Accesso (int) via (void *) che punta a (void *) che punta a (int) per typecasting e dereferencing

#include <stdio.h> 

int main(void) 
{ 
    int num = 42;    // we want to access this integer 
    void *vptrB = &num;  // pointer B points to the integer 
    void *vptrA = &vptrB;  // pointer A points to pointer B 
    printf("%d\n", * (int *) * (void **) vptrA); 
    return 0; 
} 

La memoria deve essere simile a questa:

scheme

ci sono alternative per accedere al numero intero? Qualcosa di brutto/non sicuro con l'esempio? * (int *) * (void **) vptrA è l'unico modo per accedere a num tramite vptrA e vptrB?

+3

Perché stai mantenendo i tuoi puntatori come "void *" invece di usare i tipi corretti? Dovresti provare a lavorare * con * il sistema di tipi, non combatterlo. –

+1

Ouch; ricordami di non aver bisogno di leggere il tuo codice in futuro, per favore? È doloroso capire. Se puoi fare riferimento a 'vptrB', allora puoi renderlo più semplice, ma se puoi accedere solo a' vptrA', allora quello che hai scritto sembra corretto - ma non l'ho eseguito oltre un compilatore per ricontrollare che io ' L'ho interpretato come farebbe un compilatore. –

+0

Direi che è di cattivo gusto usare "void *" in generale (specialmente in luoghi dove si potrebbe facilmente usare un puntatore digitato), e uno stile pessimo per mascherare il livello di riferimento indiretto (cioè memorizzare l'indirizzo di un 'vuoto * 'invece di un' vuoto ** '). E normalmente eviterei di lanciare nel mezzo del dereferenziamento, quindi dovrei '** ((int **) vptrA)'. – Zastai

risposta

2

Esistono alternative per accedere all'intero?

int num = 42; 
int *vptrB = &num; 
int **vptrA = &vptrB; 
// All print 42 
printf("%d\n", num); 
printf("%d\n", *vptrB); 
printf("%d\n", **vptrA); 

nulla di male/non sicuro con l'esempio?

L'utilizzo di void* per rappresentare l'indirizzo per i dati perde tipo, l'allineamento, const e volatile informazioni. void* obbliga l'uso della trasmissione per interpretare successivamente i dati di riferimento - questo è soggetto a errori. Sebbene il codice sia corretto nel cast, è soggetto a errori di manutenzione e errori di revisione del codice.

+1

usando 'void *' senza cast conserva le informazioni 'const' e' volatile'. Ovviamente puoi lanciare quelle cose, ma vale anche per 'int *' –

Problemi correlati