2015-07-28 16 views
5

Ho il codice qui sotto:Dereferenziare un puntatore nullo

#include <inttypes.h> 
#include <stdlib.h> 
struct a 
{ 
    void *p; 
}; 

int main(void) 
{ 
    struct a *ptr = malloc(sizeof(struct a)); 
    ptr->p = malloc(sizeof(uint8_t)); 
    *((uint8_t *) ptr->p) = 2; 
    return 0; 
} 

sto getto del puntatore vuoto prima di dereferencing per evitare l'avvertimento

avvertimento: dereferenziazione '* vuoto' puntatore

Sto rompendo qualsiasi regola facendo questo o questo codice è buono?

+0

Quali sospetti avete delle regole che potrebbero essere violate? –

+2

Se non c'è una ragione specifica per cui il tipo di 'p' non è solo' uint8_t * ', questo è un codice terribile. – Staven

+0

@MattMcNabb lancia il lvalue modificabile? Volevo solo confermare una volta che questo è buono o no? – Gopi

risposta

6

Sì, questo codice è legale e non causa un comportamento indefinito (a meno che malloc restituisca NULL).

3

Secondo i mandati standard, questo codice sembra ok. un puntatore a un tipo di carattere può essere utilizzato per puntare all'oggetto senza interrompere la regola di aliasing.

Per citare lo standard, capitolo §6.3.2.3

[...]. Quando un puntatore a un oggetto viene convertito in un puntatore a un tipo di carattere, il risultato punta al byte con l'indirizzo più basso dell'oggetto. Gli incrementi successivi del risultato, fino alla dimensione dell'oggetto, producono i puntatori ai byte rimanenti dell'oggetto.

+1

Il codice sarebbe OK anche se non fosse un puntatore al tipo di carattere. Poiché l'oggetto non ha un tipo dichiarato, il tipo * effettivo * per la scrittura è il tipo con cui si sta scrivendo, (e il tipo effettivo per la lettura è il tipo dell'ultima cosa scritta sull'oggetto). Scriviamo solo in questo esempio, quindi impostiamo il tipo effettivo. –

+0

@MattMcNabb Assolutamente signore. Stavo pensando come se "p" non fosse stato un "void *", quindi anche il cast di 'char *' (o equivalente) e sarebbe stato definito un ulteriore utilizzo, giusto? –

+0

nb: Penso che uint8_t non sia un tipo di carattere necessariamente (http://stackoverflow.com/questions/12666146/can-uint8-t-be-a-non-character-type) –

Problemi correlati