L Allocazione Dinamica della Memoria

Documenti analoghi
L'Allocazione Dinamica della Memoria nel linguaggio C

Corso di Informatica A.A

Allocazione statica della memoria

Gestione dinamica della memoria

Introduzione al C Lez. 4. Allocazione Dinamica della memoria

Lezione IX Gestione dinamica della memoria

Strutture Dati Dinamiche

Introduzione al C Lez. 4

Allocazione dinamica della memoria

INFORMATICA A. Titolo presentazione sottotitolo. Laboratorio n 6 Dott. Michele Zanella Ing. Gian Enrico Conti

Introduzione al C. Lezione 4 Allocazione dinamica della memoria. Rossano Venturini. Pagina web del corso

Lezione IX Gestione dinamica della memoria

Titolo presentazione INFORMATICA. sottotitolo A.A Milano, XX mese 20XX Laboratorio n 6 Ing. Gian Enrico Conti Dott.

Laboratorio di Informatica I

Il linguaggio C. Puntatori e dintorni

Allocazione dinamica della memoria

Unità Didattica 4 Linguaggio C. Vettori. Puntatori. Funzioni: passaggio di parametri per indirizzo.

Liste concatenate e allocazione dinamica

La gestione della memoria dinamica Heap

Uso avanzato dei puntatori Allocazione dinamica della memoria

Puntatori. Operazioni sui puntatori Allocazione dinamica

Strutture. Array dei nomi degli esami (MAX ESAMI è il massimo numero degli esami). Array con i crediti degli esami.

Ogni variabile in C è una astrazione di una cella di memoria a cui corrisponde un nome, un contenuto e un indirizzo.

I puntatori. DD Cap.7 pp KP Cap.6 pp

Unità 11 Allocazione dinamica

Lezione 21 e 22. Valentina Ciriani ( ) Laboratorio di programmazione. Laboratorio di programmazione. Lezione 21 e 22

Allocazione dinamica della memoria: calloc() Se T è il nomed di un tipo, la chiamata calloc(n, sizeof(t)) è equivalente a malloc(n * sizeof(t))

Introduzione al C. Unità Gestione Dinamica della Memoria

Tipi di dato personalizzati Array di struct. Tipi di dato utente. Laboratorio di Programmazione I. Corso di Laurea in Informatica A.A.

puntatori Lab. Calc. AA 2006/07 1

Prof. G. Ascia. I puntatori. Fondamenti di Informatica

Liste concatenate e allocazione dinamica

Allocazione della memoria. Allocazione dinamica della memoria. Allocazione della memoria. Allocazione automatica

Puntatori. Un puntatore contiene un numero che indica la locazione di memoria dove è presente la variabile puntata

Associazione Variabile-Indirizzo

Gestione della memoria

L'allocazione statica: L'allocazione automatica L'allocazione dinamica:

Allocazione Dinamica. Allocazione Statica. malloc() La funzione malloc()

Lezione 12: Allocazione Dinamica della Memoria

Il linguaggio C. Puntatori e dintorni

Allocazione dinamica della memoria

Informatica per Statistica Riassunto della lezioni del 14/11/2012 e 16/11/2012

LISTE E RIPASSO. Sesto Laboratorio

C: panoramica. Violetta Lonati

Allocazione dinamica della memoria

! Per quanto sappiamo finora, in C le variabili sono sempre definite staticamente

Matrici. Parte 7. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Politecnico di Milano. Strutture dati dinamiche

I puntatori e l allocazione dinamica di memoria

Corso di Informatica A.A

JAVA. import java.util.*; #include <stdio.h> public static class test { int variable; private int variable; int main (int argc, char *argv[]) {

Esercitazioni Fondamenti di Informatica

Lezione 8: Stringhe ed array multidimensionali

Introduzione al linguaggio C Puntatori

Prof. G. Ascia. Allocazione dinamica della memoria (2)

Struct, enum, Puntatori e Array dinamici

Lab 12 Allocazione dinamica della memoria

Definizione Allocazione e deallocazione di variabili Allocazione e deallocazione di vettori

Fondamenti di Informatica 2

Esercitazioni di Fondamenti di Informatica - Lez. 7 20/11/2018

Matrici. Unità 7. Domenico Daniele Bloisi. Corso di Programmazione e Metodi Numerici Ingegneria Aerospaziale BAER

Informatica 1. Corso di Laurea Triennale in Matematica. Gianluca Rossi

Per quanto sappiamo finora, in C le variabili sono sempre definite staticamente. per variabili di tipo array, in cui dover

Puntatori. Grazie ai puntatori:

La programmazione nel linguaggio C. Liste

L'allocazione dinamica della memoria

Allocazione Dinamica della memoria

L'allocazione dinamica della memoria

Strutture dati dinamiche in C. Emilio Di Giacomo

Fondamenti di Informatica 2

Corso di Fondamenti di Informatica. Puntatori e Allocazione Dinamica

Capitolo 10 - Strutture

Allocazione Dinamica della Memoria

Calcolatori Ele,ronici Lezione 9 5/12/2013

Variabili dinamiche. Obiettivi: Presentare le variabili dinamiche, allocate e deallocate nell area HEAP, e le funzioni malloc e free

Esercizio 2: Algebra dei Puntatori e Puntatori a Puntatori

Laboratorio di Informatica Ingegneria Clinica Lezione 14-16/11/2011

Strutture. Una dichiarazione struct definisce un nuovo tipo. - Può essere seguita da una lista di variabili.

Il linguaggio C. Puntatori e Array

Introduzione al linguaggio C

Prof.Ing.S.Cavalieri Puntatori e Heap in Linguaggio C. Puntatori e Heap

Array. Parte 7. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Esercitazione 11. Liste semplici

Array. Aggragati di variabili omogenee...

Consideriamo un vettore allocato dinamicamente

Fondamenti di Informatica 2

Qualsiasi programma in C++ segue lo schema: Variabili

- matrici - stringhe - file (lettura/scrittura, di testo/binari) - strutture, puntatori - allocazione dinamica della memoria (malloc)

Stringhe e allocazione dinamica della memoria

I puntatori e l allocazione dinamica di memoria

Corso di Informatica

Puntatori. Obiettivi: Richiamare quanto noto sui puntatori dal modulo A Presentare l analogia tra puntatori e vettori e l aritmetica dei puntatori

Puntatori. Obiettivi: Richiamare quanto noto sui puntatori dal modulo A Presentare l analogia tra puntatori e vettori e l aritmetica dei puntatori

Esercizi di programmazione in linguaggio C English Dictionary

Transcript:

L Allocazione Dinamica della Memoria Maurizio Palesi DIIT Università di Catania Viale Andrea Doria 6, 95125 Catania mpalesi@diit.unict.it http://www.diit.unict.it/users/mpalesi Sommario Questo documento tratta l allocazione dinamica della memoria in C. Verrà evidenziato come, alcune volte, l utilizzo di strutture dati di tipo statico non sono opportune in certi scenari applicativi. Saranno descritte in dettaglio le funzioni C per la gestione dinamica della memoria e presentati diversi esempi. Indice 1 Introduzione 1 2 Perchè Allocare Dinamicamente? 2 2.1 Sovradimensionamento.. 3 2.2 Allocazione Dinamica.. 4 3 Gestione Dinamica della Memoria 5 3.1 calloc() e malloc() 5 3.2 free().......... 6 3.3 realloc()....... 6 4 Matrici Dinamiche 6 5 Esercizi 7 1 Introduzione La scelta delle appropriate strutture dati è di fondamentale importanza per la risoluzione di un certo problema almeno tanto quanto un buon programma di manipolazione. Fin qui ci siamo occupati di strutture dati sia di tipo scalare (tipo intero, reale, carattere) sia di tipo strutturato (stringhe, vettori, e strutture). A ciascuna di esse abbiamo associato le relative rappresentazioni interne previste dal C. Le variabili corrispondenti ai tipi suddetti non possono mutare le loro caratteristiche in fase di esecuzione e pertanto sono dette statiche. Vogliamo occuparci ora di un altro tipo di variabili: quelle dinamiche cioè le variabili che possono essere create e/o accresciute in fase di esecuzione. 1

2 Perchè Allocare Dinamicamente? Il lettore potrebbe chiedersi qual è la necessità di utilizzare l allocazione statica piuttosto che quella dinamica. Si consideri per esempio il seguente frammento di codice per il calcolo della media degli elementi di un vettore. Una prima versione potrebbe essere: # d e f i n e N 1 0 main ( ) i n t v [N ], i, somma, media ; / i n s e r i m e n t o d a t i / f o r ( i = 0 ; i <N ; i ++) p r i n t f ( " I n s e r i s c i elemento %d esimo : " ) ; s c a n f ("%d ", & v [ i ] ) ; / c a l c o l o d e l l a media e v i s u a l i z z a z i o n e / somma = 0 ; f o r ( i = 0 ; i <N ; i ++) somma = somma + v [ i ] ; media = somma / N; p r i n t f ( " La mediaè : % d ", media ) ; Il problema in questo caso è che tale codice effettua la media esclusivamente di N valori. Se si volesse per esempio calcolare la media di 20 numeri piuttosto che di 10 occorrerebbe modificare N: # d e f i n e N 2 0 e ricompilare il programma. Una soluzione per per rendere il programma più flessibile sarebbe quella di chiedere all utente di inserire il numero di elementi di cui calcolare la media e quindi utilizzare tale valore in luogo di N. Chiaramente una soluzione del tipo:... i n t num ; p r i n t f ( " Di q u a n t i v a l o r i vuoi f a r e l a media? " ) ; s c a n f ( "%d ", & num ) ; i n t v [ num ] ;... non è corretta in C visto che la dichiarazione di un vettore richiede la conoscenza del numero di elementi a tempo di compilazione. Nel suddetto frammento di codice, infatti, 2

il valore della variabile num non è noto a tempo di compilazione ma soltanto a tempo di esecuzione (in questo caso dopo l esecuzione della scanf). Nelle sottosezioni successive presentiamo due diverse soluzioni a questo problema. La prima sovradimensiona il vettore mentre la seconda fa uso dell allocazione dinamica della memoria. 2.1 Sovradimensionamento Una possibile soluzione potrebbe essere quella di sovradimensionare il vettore in questo modo: # d e f i n e MAXDIM 1 0 0 main ( ) i n t v [MAXDIM ], num, i, somma, media ; p r i n t f ( " Di q u a n t i v a l o r i vuoi f a r e l a media? " ) ; s c a n f ( "%d ", & num ) ; / c o n t r o l l o se ho l e r i s o r s e n e c e s s a r i e / / per memorizzare t u t t i i d a t i / i f ( num > MAXDIM) p r i n t f ( " i l v e t t o r e òpu c o n t e n e r e a l massimo %d v a l o r i ", MAXDIM) ; e l s e / i n s e r i m e n t o d a t i / f o r ( i = 0 ; i <num ; i ++) p r i n t f ( " I n s e r i s c i elemento %d esimo : " ) ; s c a n f ("%d ", & v [ i ] ) ; / c a l c o l o d e l l a media e v i s u a l i z z a z i o n e / somma = 0 ; f o r ( i = 0 ; i <num ; i ++) somma = somma + v [ i ] ; media = somma / num ; p r i n t f ( " La media è : % d ", media ) ; 3

Il problema di questo approccio è però lo spreco di memoria. 2.2 Allocazione Dinamica Un approccio più efficiente dal punto di vista dell utilizzazione della risorsa memoria sarebbe quello di utilizzare sempre un vettore formato da un numero di elementi esattamente uguale a quelli da elaborare. main ( ) i n t v, num, i, somma, media ; p r i n t f ( " Di q u a n t i v a l o r i vuoi f a r e l a media? " ) ; s c a n f ( "%d ", & num ) ; / a l l o c o una à q u a n t i t d i memoria n e c e s s a r i a / / per memorizzare e s a t t a m e n t e num i n t e r i / / i l p u n t a t o r e v à p u n t e r e s a t t a m e n t e / / a l l i n i z i o d i q u e s t a area / v = ( i n t ) malloc ( num s i z e o f ( i n t ) ) ; / i n s e r i m e n t o d a t i / f o r ( i = 0 ; i <num ; i ++) p r i n t f ( " I n s e r i s c i elemento %d esimo : " ) ; s c a n f ("%d ", & v [ i ] ) ; / c a l c o l o d e l l a media e v i s u a l i z z a z i o n e / somma = 0 ; f o r ( i = 0 ; i <um ; i ++) somma = somma + v [ i ] ; media = somma / num ; p r i n t f ( " La mediaè : % d ", media ) ; / ora posso l i b e r a r e l area d i memoria / / p r e c e d e n t e m e n t e a l l o c a t a / f r e e ( v ) ; 4

Le funzioni malloc(), free() e diverse altre saranno discusse nella sezione successiva. 3 Gestione Dinamica della Memoria In questa sezione descriveremo in dettaglio le funzioni messe a disposizione dalla libreria standard C per la gestione dinamica della memoria. Le principali sono quattro: malloc(), calloc(), free(), ralloc() e sono accessibili includendo il file header stdlib.h: #include <stdlib.h> malloc() e calloc() allocano un blocco di memoria, free() libera un blocco di memoria precedentemente allocato e realloc() modifica le dimensioni di un blocco di memoria precedentemente allocato. 3.1 calloc() e malloc() Il prototipo delle funzioni malloc e calloc è il seguente: void c a l l o c ( i n t num_elementi, i n t dim_elemento ) ; void malloc ( d i m _ t o t a l e ) ; calloc() alloca memoria per un vettore di num_elementi elementi di dim_elemento bytes ciascuno e restituisce un puntatore alla memoria allocata. Inoltre inizializza ogni byte di tale blocco di memoria a zero. malloc() alloca dim_totale bytes di memoria e restituisce un puntatore a tale blocco. In questo caso la memoria non è inizializzata a nessun valore. Per determinare la dimensione in byte di un tipo di dato è possibile utilizzare la funzione sizeof(). Quindi, per esempio, per allocare un vettore di n elementi di tipo intero basta fare: i n t v ; v = ( i n t ) c a l l o c ( n, s i z e o f ( i n t ) ) ; Il puntatore v punterà al primo elemento di un vettore di n elementi interi. Si noti che è stato utilizzato il casting per assegnare il puntatore restituito da calloc a v. Infatti calloc restituisce un void* mentre v è un int*. Analogamente si può utilizzare la funzione malloc per ottenere lo stesso risultato: i n t v ; v = ( i n t ) malloc ( n s i z e o f ( i n t ) ) ; In questo caso occorre determinare il numero totale di bytes da allocare che è pari al numero di elementi del vettore per la dimensione in bytes del generico elemento. In questo caso poichè il vettore contiene interi, la dimensione del generico elemento è sizeof(int). 5

Sia calloc() che malloc() restituiscono NULL se non riescono ad allocare la quantità di memoria richiesta. 3.2 free() Il prototipo della funzione free() è: void f r e e ( void p t r ) ; Essa rilascia (libera o dealloca) lo spazio di memoria puntato da ptr il cui valore proveniva da una precedente malloc() o calloc() o realloc(). Se ptr è NULL nessuna operazione viene eseguita. 3.3 realloc() Il prototipo della funzione realloc() è: void r e a l l o c ( void p t r, i n t d i m _ t o t a l e ) ; Essa modifica la dimensione di un blocco di memoria puntato da ptr a dim_totale bytes. Se ptr è NULL, l invocazione è equivalente ad una malloc(dim_totale). Se dim_totale è 0, l invocazione è equivalente ad una free(ptr). Naturalmente il valore di ptr deve provenire da una precedente invocazione di malloc() o calloc() o realloc(). 4 Matrici Dinamiche Possiamo rappresentare una matrice come un vettore di vettori. Cioè l elemento -esimo di un vettore è un vettore che rappresenta le colonne della matrice. Per costruire una matrice dinamica di r righe e c colonne basterà eseguire le seguenti due operazioni: 1. Allocare dinamicamente un vettore di r puntatori (vettore delle righe). 2. Per ogni riga allocare un vettore di c elementi del tipo base considerato (vettore colonne). La Figura 1 mostra la rappresentazione grafica di una matrice dinamica. Per esempio il seguente frammento di codice definisce ed alloca una matrice dinamica di interi di r righe e c colonne. i n t m a t r i c e, i ; / a l l o c o i l v e t t o r e d e l l e r i g h e. Ogni e l e m e n t o / / d i q u e s t o v e t t o r e è un p u n t a t o r e / m a t r i c e = ( i n t ) malloc ( r s i z e o f ( i n t ) ) ; 6

0 1 2 3 4 5 6 7 8 0 1 2 3 4 Figura 1: Rappresentazione di una matrice dinamica vista come un vettore di puntatori. / per ogni r i g a a l l o c o l e c o l o n n e / m a t r i c e [ i ] = ( i n t ) malloc ( c s i z e o f ( i n t ) ) ; Per disallocare una matrice dinamica, invece, occorre procedere alla rovescia: prima si disallocano tutte le colonne quindi si disalloca il vettore dei puntatori alle colonne. / per ogni r i g a d i s a l l o c o l e c o l o n n e / f r e e ( m a t r i c e [ i ] ) ; / d i s a l l o c o i l v e r r o r e d e l l e r i g h e / f r e e ( m a t r i c e ) ; 5 Esercizi Esercizio 5.1 () Calcolare la media degli elementi di una sequenza di valori double inseriti dall utente. La fine della sequenza è identificata dal numero 0.0. Utilizzare vettori dinamici. 7

Risoluzione # i n c l u d e < s t d i o. h> # i n c l u d e < s t d l i b. h> void main ( ) double v e t t o r e, elemento, somma, media ; i n t i, j, f i n e ; v e t t o r e = NULL; / i n s e r i m e n t o d a t i / i = 0 ; f i n e = 0 ; while (! f i n e ) p r i n t f ( " I n s e r i s c i un elemento ( 0 p e r f i n i r e ) : " ) ; s c a n f ("% l f ", & elemento ) ; i f ( elemento = = 0. 0 ) f i n e = 1 ; e l s e / aumento d i 1 l a d i m e n s i o n e d e l v e t t o r e / v e t t o r e = ( double ) r e a l l o c ( v e t t o r e, ( i + 1 ) s i z e o f ( double ) ) ; v e t t o r e [ i ] = elemento ; i ++; / c a l c o l o e stampa d e l l a media / somma = 0. 0 ; f o r ( j = 0 ; j < i ; j ++) somma + = v e t t o r e [ j ] ; media = somma / i ; p r i n t f ( " La mediaè : % l f \ n ", media ) ; / d e l l o c a z i o n e d e l v e t t o r e / f r e e ( v e t t o r e ) ; 8

Esercizio 5.2 () Calcolare la trasposta di una matrice di interi allocata dinamicamente. Risoluzione # i n c l u d e < s t d i o. h> # i n c l u d e < s t d l i b. h> void main ( ) i n t m a t r i c e, t r a s p o s t a ; i n t r i g h e, c o l o n n e, r, c ; p r i n t f ( " Quante r i g h e ha l a m a t r i c e : " ) ; s c a n f ( "%d ", & r i g h e ) ; p r i n t f ( " Quante c o l o n n e ha l a m a t r i c e : " ) ; s c a n f ( "%d ", & c o l o n n e ) ; / a l l o c a z i o n e d e l l a m a t r i c e / m a t r i c e = ( i n t ) malloc ( r i g h e s i z e o f ( i n t ) ) ; f o r ( r = 0 ; r < r i g h e ; r ++) m a t r i c e [ r ] = ( i n t ) malloc ( c o l o n n e s i z e o f ( i n t ) ) ; / i n s e r i m e n t o d a t i / f o r ( r = 0 ; r < r i g h e ; r ++) f o r ( c = 0 ; c< c o l o n n e ; c ++) p r i n t f ( " I n s e r i s c i elemento d i r i g a %d e c o l o n n a %d : ", r, c ) ; s c a n f ("%d ", & m a t r i c e [ r ] [ c ] ) ; / a l l o c o l a m a t r i c e t r a s p o s t a / t r a s p o s t a = ( i n t ) malloc ( c o l o n n e s i z e o f ( i n t ) ) ; f o r ( c = 0 ; c< c o l o n n e ; c ++) t r a s p o s t a [ c ] = ( i n t ) malloc ( r i g h e s i z e o f ( i n t ) ) ; 9

/ c a l c o l o d e l l a t r a s p o s t a / f o r ( r = 0 ; r < r i g h e ; r ++) f o r ( c = 0 ; c< c o l o n n e ; c ++) t r a s p o s t a [ c ] [ r ] = m a t r i c e [ r ] [ c ] ; / stampo l a t r a s p o s t a / p r i n t f ( " La t r a s p o s t a è : \ n " ) ; f o r ( c = 0 ; c< c o l o n n e ; c ++) f o r ( r = 0 ; r < r i g h e ; r ++) p r i n t f ("%d ", t r a s p o s t a [ c ] [ r ] ) ; p r i n t f ( " \ n " ) ; / d e a l l o c o l a m a t r i c e / f o r ( r = 0 ; r < r i g h e ; r ++) f r e e ( m a t r i c e [ r ] ) ; f r e e ( m a t r i c e ) ; / d e a l l o c o l a t r a s p o s t a / f o r ( c = 0 ; c< c o l o n n e ; c ++) f r e e ( t r a s p o s t a [ c ] ) ; f r e e ( t r a s p o s t a ) ; Esercizio 5.3 () Calcolare la trasposta di una matrice di interi allocata dinamicamente. Strutturare il programma a funzioni. Risoluzione # i n c l u d e < s t d i o. h> # i n c l u d e < s t d l i b. h> t y p e d e f i n t T Matrice ; / d i c h i a r a z i o n e d e l l e f u n z i o n i ( p r o t o t i p i ) 10

/ void L eggirighecolonne ( i n t r, i n t c ) ; T Matrice A l l o c a M a t r i c e ( i n t r, i n t c ) ; void I n s e r i m e n t o ( T Matrice mat, i n t r, i n t c ) ; void C a l c o l a T r a s p o s t a ( T Matrice mat, T Matrice t r a s p, i n t r, i n t c ) ; void V i s u a l i z z a M a t r i c e ( T Matrice mat, i n t r, i n t c ) ; void D e a l l o c a M a t r i c e ( T Matrice mat, i n t r ) ; / programma p r i n c i p a l e / void main ( ) T Matrice m a t r i c e, t r a s p o s t a ; i n t r i g h e, c o l o n n e, r, c ; L eggirighecolonne(& r i g h e, & c o l o n n e ) ; m a t r i c e = A l l o c a M a t r i c e ( r i g h e, c o l o n n e ) ; I n s e r i m e n t o ( m a t r i c e, r i g h e, c o l o n n e ) ; p r i n t f ( " Hai i n s e r i t o l a m a t r i c e : \ n " ) ; V i s u a l i z z a M a t r i c e ( m a t r i c e, r i g h e, c o l o n n e ) ; t r a s p o s t a = A l l o c a M a t r i c e ( c o l o n n e, r i g h e ) ; C a l c o l a T r a s p o s t a ( m a t r i c e, t r a s p o s t a, r i g h e, c o l o n n e ) ; p r i n t f ( " La t r a s p o s t a è : \ n " ) ; V i s u a l i z z a M a t r i c e ( t r a s p o s t a, c o l o n n e, r i g h e ) ; D e a l l o c a M a t r i c e (& m a t r i c e, r i g h e ) ; D e a l l o c a M a t r i c e (& t r a s p o s t a, c o l o n n e ) ; / d e f i n i z i o n e d e l l e f u n z i o n i / 11

void L eggirighecolonne ( i n t r, i n t c ) p r i n t f ( " Quante r i g h e ha l a m a t r i c e : " ) ; s c a n f ( "%d ", r ) ; p r i n t f ( " Quante c o l o n n e ha l a m a t r i c e : " ) ; s c a n f ( "%d ", c ) ; T Matrice A l l o c a M a t r i c e ( i n t r, i n t c ) T Matrice mat ; i n t i ; mat = ( T Matrice ) malloc ( r s i z e o f ( i n t ) ) ; mat [ i ] = ( i n t ) malloc ( c s i z e o f ( i n t ) ) ; return mat ; void I n s e r i m e n t o ( T Matrice mat, i n t r, i n t c ) i n t i, j ; f o r ( j = 0 ; j <c ; j ++) p r i n t f ( " I n s e r i s c i elemento d i r i g a %d e c o l o n n a %d : ", i, j ) ; s c a n f ("%d ", & mat [ i ] [ j ] ) ; void C a l c o l a T r a s p o s t a ( T Matrice mat, T Matrice t r a s p, i n t r, i n t c ) i n t i, j ; f o r ( j = 0 ; j <c ; j ++) t r a s p [ j ] [ i ] = mat [ i ] [ j ] ; 12

void V i s u a l i z z a M a t r i c e ( T Matrice mat, i n t r, i n t c ) i n t i, j ; f o r ( j = 0 ; j <c ; j ++) p r i n t f ("%d ", mat [ i ] [ j ] ) ; p r i n t f ( " \ n " ) ; void D e a l l o c a M a t r i c e ( T Matrice mat, i n t r ) i n t i ; f r e e ( ( mat ) [ i ] ) ; f r e e ( mat ) ; 13