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

Documenti analoghi
Allocazione statica della memoria

Gestione dinamica della memoria

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

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

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

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

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

Allocazione dinamica della memoria

Unità 11 Allocazione dinamica

Il linguaggio C. Puntatori e dintorni

Strutture Dati Dinamiche

Allocazione dinamica della memoria

Introduzione al C Lez. 4

L Allocazione Dinamica della Memoria

Introduzione al C Lez. 4. Allocazione Dinamica della memoria

La gestione della memoria dinamica Heap

Lezione 12: Allocazione Dinamica della Memoria

Corso di Informatica A.A

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

L'Allocazione Dinamica della Memoria nel linguaggio C

Allocazione dinamica della memoria

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

Introduzione al C. Unità Gestione Dinamica della Memoria

Fondamenti di Informatica T. Linguaggio C: i puntatori

Allocazione dinamica della memoria

Gestione della memoria

puntatori Lab. Calc. AA 2006/07 1

La programmazione nel linguaggio C. Liste

Corso di Fondamenti di Informatica. Puntatori e Allocazione Dinamica

Uso avanzato dei puntatori Allocazione dinamica della memoria

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

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

Università degli Studi di Cassino e del Lazio Meridionale Corso di Fondamenti di Informatica Allocazione dinamica di memoria

Allocazione Dinamica della Memoria

Laboratorio di Informatica I

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

Lezione 6: Array e puntatori

Struct, enum, Puntatori e Array dinamici

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

Introduzione al linguaggio C Puntatori

Il puntatore. Il puntatore

Non ci sono vincoli sul tipo degli elementi di un vettore Possiamo dunque avere anche vettori di

&v restituisce l indirizzo della zona di memoria allocata per v.

Problema. Vettori e matrici. Vettori. Vettori

Funzioni, Stack e Visibilità delle Variabili in C

Memoria dinamica. Mauro Fiorentini, Univ. di Milano, 2019 M. Fiorentini Il linguaggio C - 467

Liste concatenate e allocazione dinamica

Corso di Programmazione I

Corso di Informatica A.A

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

Puntatori. Operazioni sui puntatori Allocazione dinamica

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

ARRAY DI PUNTATORI. ARRAY DI PUNTATORI Non ci sono vincoli sul tipo degli elementi di un vettore Possiamo dunque avere anche vettori di puntatori

Puntatori. Unità 6. Corso di Laboratorio di Informatica Ingegneria Clinica BCLR. Domenico Daniele Bloisi

passaggio di vettori come parametri di funzioni/procedure. I Quando si passa un vettore come parametro ad una funzione, in

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

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

Funzioni, Stack e Visibilità delle Variabili in C

Puntatori. Unità 6. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

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

Esercizi con Array. Unità 7. Corso di Laboratorio di Informatica Ingegneria Clinica BCLR. Domenico Daniele Bloisi

Corso di Fondamenti di Informatica

Ingegneria Elettronica Ingegneria delle Telecomunicazioni (J-Z) Ing. Antonio Monteleone A.A. 2001/02 3 ciclo

Programmazione II. Lezione 7. Daniele Sgandurra 9/11/2010.

VARIABILI AUTOMATICHE E DINAMICHE. Manuale linguaggio C

Capitolo 10 - Strutture

I puntatori. Un puntatore è una variabile che contiene l indirizzo di un altra variabile. puntatore

Il linguaggio C. Puntatori e dintorni

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

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

Esercizi Array Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

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

Applicando lo stesso meccanismo al tipo puntatore, possiamo dichiarare un array di puntatori:

Introduzione al linguaggio C Puntatori

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

C: panoramica. Violetta Lonati

Lezione 8: Stringhe ed array multidimensionali

I puntatori e l allocazione dinamica di memoria

Esercizio 2: Algebra dei Puntatori e Puntatori a Puntatori

Strutture Dinamiche. Strutture Dinamiche

Allocazione dinamica

20. Gestione della memoria. Andrea Marongiu Paolo Valente

Elementi di Informatica

Laboratorio di Informatica

Tipi derivati. Strutture Matrici typedef enum

Le strutture. Una struttura C è una collezione di variabili di uno o più tipi, raggruppate sotto un nome comune.

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

Linguaggi di Programmazione Corso C. Parte n.10 Gestione della Memoria. Nicola Fanizzi

Corso di Informatica

Politecnico di Milano. Strutture dati dinamiche

Il linguaggio C. Puntatori e Array

definisce un vettore di 4 puntatori a carattere (allocata memoria per 4 puntatori)!

Precedenza e associatività. Complementi sul C - 2. Esempi. Esempi

La Gestione della Memoria. Carla Binucci e Walter Didimo

Transcript:

Allocazione dinamica della memoria Ver. 2.4 2010 - Claudio Fornaro - Corso di programmazione in C Allocazione della memoria Il termine allocazione viene utilizzato per indicare l assegnazione di un blocco di memoria RAM ad un programma La memoria può essere allocata nello stack, nello heap o nel Data Segment di un programma La memoria può essere allocata: Al run-time (dal programma in esecuzione) Al compile-time (dal compilatore) La memoria può essere rilasciata (deallocata, resa disponibile) automaticamente o a richiesta Al run-time la dimensione della memoria allocata può essere fissa o modificabile 2 Allocazione della memoria Il programma compilato è costituito da due parti distinte: STACK Code Segment Data Segment Stack e heap Quando il programma viene eseguito, il Sistema Operativo alloca uno spazio di memoria HEAP per allocarvi stack e heap DATA Se lo spazio per stack e heap ha dimensione fissa (dipende CODE dal S.O.), questo può esaurirsi per effetto di ripetute chiamate a funzione (stack) non chiuse o allocazioni dinamiche (heap) 3 Allocazione automatica Si ha allocazione automatica di un blocco di memoria quando in una funzione (main incluso) viene definita una variabile locale Il blocco (la variabile) viene creato: al run-time nello stack La dimensione è non è modificabile al run-time (è nota al compile-time, limite del C89/C90) Il blocco non è rilasciabile esplicitamente, ma avviene automaticamente quando termina la funzione dove è definita la variabile int vett[1000]; (interno ad una funzione) 4

Allocazione statica 5 Allocazione dinamica 6 Si ha allocazione statica di un blocco di memoria quando viene definita una variabile di classe di allocazione statica (esterna o interna con la clausola static) Il blocco di memoria viene allocato: al compile-time nel Data Segment La dimensione è non è modificabile al run-time (è nota al compile-time ) Il blocco è non rilasciabile (non è riutilizzabile per altre allocazioni) int vett[1000]; (esterno alle funzioni) Si ha allocazione dinamica di un blocco di memoria quando si usano opportune funzioni Il blocco di memoria viene allocato: al run-time nello heap La dimensione è indicata alle funzioni ad ogni richiesta (più grande è il blocco richiesto, più tempo ci mette la funzione a riservarlo) Il blocco è rilasciabile (per poter essere utilizzato per altre allocazioni dinamiche) solo esplicitamente per mezzo di opportune funzioni (non è automatico) 7 8 Si trovano in <stdlib.h> Allocano un generico blocco contiguo di byte Restituiscono l indirizzo di memoria (di tipo puntatore-a-void) del primo byte del blocco, (NULL in caso di errore: allocazione non riuscita, controllare sempre) malloc(dim) alloca un blocco di byte non inizializzato composto da un numero di byte pari a dim int *p; p=(int *)malloc(sizeof(int)); Il blocco di byte non ha di per sé alcun tipo, il cast sul puntatore restituito fa sì che il blocco di byte sia considerato dal compilatore come avente il tipo indicato nel cast Nell esempio il cast (int *) fa sì che il compilatore consideri il blocco di byte come vettore di interi Non si può applicare l operatore sizeof a un blocco di memoria allocato dinamicamente in quanto sizeof viene valutato dal compilatore

9 10 Il cast esplicito non sarebbe necessario per un compilatore C standard, perché l assegnazione di un puntatore void ad un puntatore non-void non lo richiede necessariamente Alcuni compilatori (in particolare quelli che compilano anche codice C++) lo richiedono comunque e quindi è bene aggiungerlo, anche per chiarezza e documentazione calloc(numogg, dimogg) richiede l allocazione di un blocco di byte inizializzati a 0 di dimensioni tali da contenere un vettore di numogg elementi, ciascuno di dimensioni dimogg byte, restituisce un puntatore void al primo byte (o NULL) 11 12 realloc(punt, dimogg) modifica la dimensione dell oggetto puntato da punt portandola a dimogg byte, restituisce il puntatore al nuovo blocco di byte Poiché per aumentare il blocco di memoria e mantenerne le celle contigue potrebbe essere necessario allocare un blocco nuovo e ricopiarvi i valori del blocco di partenza, il puntatore restituito può essere diverso da quello che punta al blocco di iniziale punt I contenuti del blocco sono preservati (tranne la parte che viene rimossa se la dimensione è inferiore alla precedente) Se la nuova dimensione è maggiore della precedente, la parte aggiuntiva non è inizializzata In caso di errore restituisce NULL e non modifica l oggetto puntato da punt

Rilascio della memoria La memoria allocata dinamicamente non viene rilasciata automaticamente (ovviamente questo capita comunque quando il programma termina in quanto tutta la memoria associata al programma viene rilasciata) Il C non ha un garbage collector che recupera al run-time la memoria inutilizzata Al run-time la memoria può essere rilasciata solo in modo esplicito, questo permette di riutilizzare quella porzione di memoria per servire successive allocazioni 13 Rilascio della memoria free(punt) rilascia il blocco di memoria puntata dal puntatore punt (il sistema mantiene memoria del numero di byte che era stata allocato) Alcuni compilatori (in particolare i compilatori C++) richiedono un cast di punt a (void *): free((void *)punt); 14 Rilascio della memoria Se un puntatore p punta ad una variabile dinamica contenente un puntatore q ad un altra variabile dinamica, bisogna rilasciare prima q e poi p: free(p->q); free(p); p struct a b q c 15 Variabile scalare Istanziazione di una variabile scalare: double *p; p=(double *)malloc(sizeof(double)); *p = 1.9; 16

Vettore unidimensionale int *p; p=(int *)malloc(sizeof(int)*100); Viene allocato un blocco di byte delle dimensioni di 100 int, è l assegnazione ad un puntatore-a-int (il cast è opzionale) che fa sì che il C lo veda come un vettore-di-int *p = 3; equivalenti p[0] = 3; *(p+12) = 19; equivalenti p[12] = 19; Allocazione equivalente (ma inizializzata a 0): p=(int *)calloc(100, sizeof(int)); 17 Vettore di strutture struct s {int x; int y;} *p, var; p=(struct s *)malloc(sizeof(struct s)*100); oppure (equivalente): p=(struct s *)malloc(sizeof(var)*100); oppure (equivalente): p=(struct s *)malloc(sizeof(*p)*100); In tutti e tre gli esempi si alloca un blocco di memoria in grado di contenere 100 elementi (consecutivi) di tipo struct s, l assegnazione ad un puntatore-a-struct-s che fa sì che il C lo veda come un vettore-di-struct-s p[12].x = 19; 18 Matrice bidimensionale Con vettore di puntatori a Tipo, array1 blocco non contiguo: int **array1; array1=(int **)malloc(nr*sizeof(int *)); for (i=0; i<nr; i++) array1[i]=malloc(nc*sizeof(int)); array1[riga][colonna] = 12; Crea un vettore di NR puntatori e per ogni puntatore alloca un vettore di int di lunghezza NC; NR e NC possono essere variabili 19 Matrice bidimensionale Con vettore di puntatori a Tipo, blocco contiguo: array2 int **array2; array2=(int **)malloc(nr*sizeof(int *)); array2[0]=(int*)malloc(nr*nc*sizeof(int)); for (i=1; i<nr; i++) array2[i]=array2[0]+i*nc; array2[riga][colonna] = 12; Crea un vettore di NR puntatori, alloca un blocco per tutta la matrice, calcola e assegna ad ogni puntatore l indirizzo di ciascuna riga; NR e NC possono essere variabili 20

Matrice bidimensionale Con vettore di Tipo, simulato con calcolo esplicito: array3 int *array3; array3=(int *)malloc(nr*nc*sizeof(int)); array3[riga*nc + colonna] = 12; Crea un blocco per tutta la matrice e accede agli elementi calcolandone la posizione (offset) riferita al primo elemento, la matrice in realtà è un vettore; NR e NC possono essere variabili 21 Matrice bidimensionale Con puntatore a vettori di Tipo, blocco contiguo: array4 int (*array4)[numcol]; array4=(int (*)[NUMCOL]) malloc(nr*sizeof(*array4)); array4[riga][colonna] = 12; Crea un blocco per tutta la matrice e lo fa puntare da un puntatore (notare il cast); NR può essere variabile, NUMCOL è una costante Il tipo di array4 è puntatore a vettore-di- NUMCOL-int, *array4 è un vettore di NUMCOL-int e la sua dimensione quella di una riga della matrice (NUMCOL) 22 Passaggio di matrice dinamica Funzione che accetta una matrice contigua di dimensioni note al run-time: int f2(int *arrayp,int rows,int cols) {... per accedere a matrice[i][j], si deve usare arrayp[i*cols+j] } Chiamate: f2(array2[0], righe, colonne); f2(array3, righe, colonne); f2((int *)array4, righe, colonne); Nell ultima, si può usare *array4 che essendo un vettore-di-int decade a puntatore-a-int 23 Passaggio di matrice dinamica Non può funzionare con array1 che non è stato creato come blocco contiguo di byte f2 accetta anche una matrice statica: int array[nr][nc]; In genere questo funziona correttamente poiché gli elementi sono allocati contiguamente riga per riga: f2(array[0], NR, NC); Ma f2 vede la matrice come un vettore e questo non è strettamente conforme allo standard perché l accesso ad elementi oltre la fine della prima riga è considerato indefinito, cioè l accesso a (&array[0][0])[x] non è definito per x >= NC 24

Passaggio di matrice dinamica Funzione che accetta una matrice anche non contigua di dimensioni note al run-time: int f3(int **arrpp,int rows,int cols) { si accede direttamente ad arrpp[i][j] } Chiamate: f3(array1, righe, colonne); f3(array2, righe, colonne); f3 non accetta direttamente una matrice statica come array perché, nel passaggio alla funzione, array decade non in un *int, non in un **int, ma in un int (*)[NC] 25 Passaggio di matrice dinamica Per passare a f3 una matrice statica è possibile creare un vettore dinamico di puntatori alle righe della matrice statica (come array2) e utilizzare questo nella funzione, il vettore di puntatori può essere definito: nel chiamante prima della chiamata alla funzione, alla funzione viene passato il puntatore al vettore dinamico nella funzione stessa, a cui viene passato il puntatore al primo elemento della matrice perché la funzione possa creare e inizializzare il vettore dinamico, il puntatore deve essere passato tramite un altro puntatore come richiesto dalla funzione 26 Esercizi 1. Si scriva un programma che ordini in senso crescente i valori contenuti in un file di testo e li scriva in un altro. Non è noto a priori quanti siano i valori contenuti nel file. Si utilizzi una funzione per l ordinamento. Il programma, per allocare un vettore dinamico di dimensione appropriata, nel main: 1. conta quanti sono i valori leggendoli dal file e scartandoli 2. crea il vettore dinamico di dimensione adeguata 3. lo riempie ri-leggendo il file 4. lo passa alla funzione di ordinamento 5. scrive il file di output con il contenuto del vettore riordinato. 27 Esercizi 2. Si realizzi una funzione con prototipo identico alla f2 descritta precedentemente (salvo il tipo restituito che qui sia void) che riempia gli elementi della matrice con numeri progressivi e li visualizzi. In seguito si scriva un main che definisca i vettori statici e dinamici indicati precedentemente: array (5x15), array2 (20x10), array3 (20x10) e array4 (20x10) e li passi a questa funzione. 28

Esercizi 3. Si scrivano due funzioni int somma1(int *v,int nrows,int ncols); int somma2(int **v,int nrows,int ncols); che calcolino la somma degli elementi di una matrice di int passata per argomento insieme alle sue dimensioni. Si predisponga un main che crei una matrice statica ms 10x20 e una dinamica md 20x30 contigua come vettore di puntatori a int (come array2) e su ciascuna chiami le due funzioni. Il passaggio della matrice statica a somma2()può essere risolto con uno dei due metodi indicati. 29