2009-06-04 14 views
51

Volevo chiedere il seguente caso:Devo castare esplicitamente il valore di ritorno di malloc()?

char *temp; 
temp = malloc(10); 

Dato il tipo di ritorno di malloc è void*, sarà il puntatore restituito dalla malloc essere implicitamente in char* tipo prima di essere assegnato alla temperatura? Cosa dice lo standard al riguardo?

Se la nostra variabile puntatore è un certo tipo struct per esempio:

struct node *temp; 
temp = (struct node *)malloc(sizeof(struct node)); 

Se allocare memoria per temperatura, senza il cast a struct node* tipo, sarà implicitamente in struct node* tipo o è necessario per lanciare in modo esplicito a struct node* tipo?

+7

Se è necessario compilare il codice con un compilatore C++ anziché con un compilatore C, è necessario il cast. Di conseguenza, la maggior parte del mio codice include il cast esplicito, anche se la pura C non lo richiede. Di solito lo taggo con/* = C++ = */per indicare perché. –

+0

Anche se non necessario, per me mi aiuta a leggere il codice in seguito con poca verbosità. – Xolve

+2

Vedere anche [questa domanda] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc/605858#605858). – unwind

risposta

33

Un puntatore del vuoto in C può essere assegnato a qualsiasi puntatore senza un cast esplicito.

+9

Non penso si applichi ai puntatori di funzione. –

+11

C non definisce se è possibile eseguire il cast di puntatori di funzione su puntatori senza funzione o viceversa. C++ lo proibisce esplicitamente e C++ 1x lo supporta in modo condizionale –

+10

E POSIX (almeno per il 2008) richiede che i puntatori di funzione abbiano le stesse dimensioni dei puntatori di dati, dove lo standard C non lo definisce. –

10

C esegue implicitamente da e verso void*, quindi il cast verrà eseguito automaticamente. In C++ solo la conversione da avoid* viene eseguita implicitamente, per l'altra direzione è richiesto un cast esplicito.

+2

Nota C++ supporta la conversione in un void * senza cast. –

3

In C++ è necessario eseguire il cast esplicito, ma questo è solo il linguaggio che ti dice di farlo.
In c non c'è davvero alcun bisogno di trasmettere, la memoria è solo memoria - Dovrò fare una ricerca per vedere se l'ultimo standard C lo richiede.

+2

Lo standard C99 non richiede il cast. –

49

Se ti piace la mentalità "non ripeterti", dovrebbe essere attraente che non sia necessario ripetere il nome del tipo dalla dichiarazione della variabile, nella chiamata malloc(). Perché, come ha sottolineato la gente, non è così: i puntatori vengono convertiti in e da void * senza perdita, ad eccezione dei puntatori di funzione.

Inoltre, in questa nota, non è necessario ripetersi con l'uso di sizeof. Il tuo secondo esempio, in sede di assegnazione di una struttura, può essere scritto in questo modo:

struct node *temp; 
temp = malloc(sizeof *temp); 

che a mio modesto parere, non così è il miglior modo .

Evitare di ripetere te stesso riduce il numero di cose che scrivi, il che a sua volta riduce il rischio che una di quelle cose sia sbagliata.

Nota l'asterisco nell'argomento sizeof, che significa "la dimensione dell'oggetto puntato da questo puntatore", che è ovviamente uguale alla "dimensione del tipo struct node" ma senza ripetere il nome del tipo. Questo perché sizeof calcola (in fase di compilazione!) La dimensione dell'espressione che è il suo argomento. Per questo caso. Proprio come sizeof 3 calcola la dimensione di un'espressione di tipo int, sizeof *temp calcola la dimensione di un'istanza di struct node.

Certo, si fa ripetere qualcosa, vale a dire il nome della variabile stessa, ma che è spesso un'espressione semplice e più facile da ottenere, e può anche essere più facile per il compilatore individuare un errore.

+6

+1 sizeof * temp – diapir

+3

Questa è un'istanza in cui l'applicazione di DRY è una pratica di programmazione non sicura (vedere il collegamento che segue). L'argomento secondo cui evitare la ripetizione riduce gli errori è contestuale. Quando si tratta di puntatori in C, così infame per l'ambiguità, ciò porterà a cattivo juju. Preferisco essere prolisso e ripetere i cast per trovare problemi al momento della compilazione (al contrario del tempo di esecuzione): https://www.securecoding.cert.org/confluence/display/seccode/MEM02-C.+Immediately+cast+ + risultato + di + a + memoria + allocazione + funzione + chiamata + in + a + puntatore + a + il + assegnato + tipo –

+3

Come al solito, securecoding.cert.org è pieno di merda. O, più educatamente, ogni singolo articolo che ho letto su quel sito è pieno di informazioni errate (pensate a 'ftell' vs' fstat'), uno stile che è ampiamente accettato di essere cattivo e dannoso, e/o semplicemente programmazione "sicurezza" del carico-culto. –

Problemi correlati