12/02/21 7:20
AldoBaldo
"Ispirato" dalla brevissima discussione in un altro filone di discussione* in questo stesso forum, ho riscritto una funzione destinata a creare matrici dinamiche in C adatte per qualsiasi tipo di dati. In questa nuova versione ho tentato di ridurre la quantità dei cast di tipo tramite l'uso di size_t in luogo di void*, ma non sono sicuro che si tratti di una pratica accettabile. Io l'ho provato e, con la configurazione di IDE, compilatore e sistema operativo che uso, sembra funzionare tutto a dovere. Qualcuno sa darmi conferma o smentita circa la validità del procedimento che ho impiegato? Ovvero...
1) E' ammissibile trasformare un void* in un size_t e trattarlo come se fosse un semplice valore numerico?
2) E' garantito che size_t possa SEMPRE contenere il valore di un puntatore?
A me pare che la risposta sia sì per entrambi i quesiti, ma al mio livello limitato di esperienza il rischio di incappare in qualche "situazione indefinita" esiste sempre.
* il filone di discussione originale:
pierotofy.it/pages/extras/forum/2/1066990-[risolto_passare_matrice_dinamica_a_routine_in_c/
1) E' ammissibile trasformare un void* in un size_t e trattarlo come se fosse un semplice valore numerico?
2) E' garantito che size_t possa SEMPRE contenere il valore di un puntatore?
A me pare che la risposta sia sì per entrambi i quesiti, ma al mio livello limitato di esperienza il rischio di incappare in qualche "situazione indefinita" esiste sempre.
/*============================================================================== Alloca dinamicamente spazio in memoria per una matrice di qr*qc elementi di dimensioni dim_el byte ciascuno. L'area della memoria allocata riservata ai dati viene inizializzata azzerandola. In caso di successo, restituisce un void* che deve essere assegnato ad un puntatore a doppia indirezione di tipo corrispondente al tipo di dati che si intende immagazzinare nella matrice appena creata. La matrice puo' essere regolarmente impiegata con i classici operatori di indicizzazione (matrice[riga][colonna]). La memoria allocata deve essere liberata dal chiamante tramite free(). In caso di errore restituisce NULL e nessuna memoria risulta allocata. PARAMETRI qr quantita' di righe nella matrice qc quantita' di colonne nella matrice dim_el dimensioni (in byte) di un elemento della matrice VALORE DI RITORNO un puntatore generico allo spazio di memoria allocato dinamicamente e in grado di contenere la matrice ESEMPIO int main() { const size_t qr = 6; const size_t qc = 4; // crea una matrice di 6x4 elementi in // grado di contenere valori di tipo int int **m = crea_matrice( qr, qc, sizeof(int) ); if( m ) { size_t r, c; // popola la matrice for( r=0; r<qr; ++r ) for( c=0; c<qc; ++c ) m[r][c] = 10*r+c; // mostra il contenuto della matrice for( r=0; r<qr; ++r ) for( c=0; c<qc; ++c ) printf( "%d%c", m[r][c], c!=qc-1?' ':'\n' ); // libera la memoria allocata free( m ); m = NULL; } return 0; } ==============================================================================*/ void *crea_matrice( size_t qr, size_t qc, size_t dim_el ) { static const size_t dim_ptr = sizeof( void* ); void *m = calloc( qr*dim_ptr + qr*qc*dim_el, 1 ); if( m ) { size_t pp = (size_t)m; /* pp: puntatore a puntatore */ size_t pr = pp + qr*dim_ptr; /* pr: puntatore a una "riga" */ while( qr-- ) { *((size_t*)pp) = pr; /* colloca il puntatore ad una ** ** riga nella posizione opportuna */ pr += qc*dim_el; /* rileva il valore del puntatore ** ** alla riga successiva */ pp += dim_ptr; /* avanza pp alla posizione del ** ** puntatore alla riga successiva */ } } return m; }
* il filone di discussione originale:
pierotofy.it/pages/extras/forum/2/1066990-[risolto_passare_matrice_dinamica_a_routine_in_c/
Ultima modifica effettuata da AldoBaldo 12/02/21 7:49
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.