Domanda

Ho una funzione che crea una serie di puntatori.La funzione che alloca la memoria restituisce il nuovo puntatore alla memoria tramite un parametro passato alla funzione.Il codice più semplice che può riprodurre il problema è il seguente:

void foo (void** new_mem, size_t bytes)
{
    *new_mem = malloc(bytes);
}

int main (void)
{
    int** ptr_arr; // Want to create an array of pointers

    foo(&ptr_arr, sizeof(int*)*100); // Create an array size of 100
                                     // compiler emits warning: 
                                     // 'void **' differs in levels of indirection from 'int ***'

    return 0;
}

Potrei lanciare il primo parametro passato a foo in questo modo:'(void**)&ptr_arr' per eliminare l'avviso, tuttavia, mi chiedo:Esiste una soluzione più adeguata?

È stato utile?

Soluzione

Sebbene ci sia una conversione garantita da int * A void *, non esiste tale garanzia per la conversione da int ** A void **.Per pensare al motivo per cui ciò potrebbe accadere, considera che an int * potrebbe effettivamente essere più piccolo di a void *.Di conseguenza, utilizzando a void ** puntatore per camminare su un array di int *s camminerà nel passo sbagliato e otterrà i dati sbagliati.Inoltre, non c'è alcuna garanzia che ciò avvenga int * utilizzerà la stessa rappresentazione di void *, solo che esiste un modo per convertire tra loro.

In pratica, non conosco nessuna macchina in cui questo fallirà.Ma non è garantito dallo standard.

MODIFICARE:eek, e quello che dicono tutti riguardo al superamento di un int ***.Ma anche se superi un int **, resta valido quanto sopra.

EDIT2:le FAQ di comp.lang.c hanno un ottima discussione a questo proposito.

Altri suggerimenti

Il problema è che stai prendendo l'indirizzo di un puntatore doppio e lo passi a un parametro puntatore doppio.Prendendo l'indirizzo di un valore si crea un puntatore quindi si finisce con un puntatore triplo int*** ecco perché ricevi l'errore.

Trasmettere il risultato a void** tecnicamente funzionerà qui, anche se rasenta un abuso del sistema dei tipi.

Il problema è che ptr_arr è già un file int **, quando fai un &ptr_arr, verrà visualizzato come int *** , quindi quello che stai facendo non è corretto.

Quindi, puoi semplicemente passare ptr_arr se la tua intenzione è passare an int **

Inoltre, ritengo che il tuo codice possa funzionare bene con una pulizia.Il tuo approccio sembra essere sbagliato.

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