C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria...

34
C. Gaibisso Programmazione di Calcolatori Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria 1

Transcript of C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria...

Page 1: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Programmazione di CalcolatoriProgrammazione di Calcolatori

Lezione XVIAllocazione dinamica

della memoria

Programmazione di Calcolatori: allocazione dinamica della memoria 1

Page 2: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Operatore sizeof()Operatore sizeof()

Programmazione di Calcolatori: allocazione dinamica della memoria 2

• Buffer:

in questa lezione per buffer intenderemo una sequenza contigua di byte (locazioni) in memoria centrale

• Sintassi:

sizeof(tipo_di_dato)

con tipo_di_dato identificatore di tipo predefinito o non

•Valore:

numero di byte utilizzati per rappresentare un valore di tipo tipo_di_dato

Page 3: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Operatore di castingOperatore di casting

Programmazione di Calcolatori: allocazione dinamica della memoria 3

• Sintassi:

(tipo_di_dato) espressione

con tipo_di_dato identificatore di tipo predefinito o non

•Valore:

il valore di espressione convertito in un valore di tipo tipo_di_dato

Page 4: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Il tipo size_t Il tipo size_t

Programmazione di Calcolatori: allocazione dinamica della memoria 4

• Definizione:

typedef unsigned int size_t;

utilizzato per rappresentare dimensioni

• Range di rappresentazione:

tra 0 e 2sizeof(size_t)*8

-1

Page 5: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso Direttiva per il Direttiva per il preprocessorepreprocessore

Programmazione di Calcolatori: allocazione dinamica della memoria 5

Attenzione!!!

Le librerie del C mettono a disposizione del programmatore un insieme di

funzioni per la gestione della memoria. Per utilizzare tali funzioni all’interno di un file è necessario includere in testa

allo stesso la direttiva per il preprocessore:

# include <stdlib.h>

Page 6: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione malloc()La funzione malloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 6

• Signature (firma):

void *malloc(size_t size);

• Modifiche allo stato della memoria:

alloca un buffer di memoria di size byte

• Valore restituito:

- l’indirizzo del primo byte del buffer, in caso di successo

- il valore NULL altrimenti

Page 7: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione free()La funzione free()

Programmazione di Calcolatori: allocazione dinamica della memoria 7

• Signature:

void free(void *ptr);

• Modifiche allo stato della memoria:

rilascia il buffer di memoria, di indirizzo iniziale ptr, allocato da una precedente chiamata alla malloc(), calloc() o realloc()

Page 8: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni malloc() e free()Le funzioni malloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 8

// sorgente: Lezione_XVI\malloc.c// illustra il corretto utilizzo dalla funzione malloc() e della free()// inclusione del file di intestazione della libreria standard che// contiene definizioni di macro, costanti e dichiarazioni di funzioni// e tipi funzionali alle varie operazioni di I/O#include <stdio.h>// inclusione del file di intestazione della libreria standard che// contiene definizioni di macro, costanti e dichiarazioni di funzioni// di interesse generale#include <stdlib.h>// visualizza il contenuto di un buffer di interivoid VisBuffInt(int *ptr, size_t nro_val) { // definisce la variabile necessaria a muoversi sul buffer size_t curs; // attraversa il buffer visualizzandone il contenuto for (curs = 0; curs <= dim-1; curs++) printf("\n%d", ptr[curs]); };

continua …

Page 9: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni malloc() e free()Le funzioni malloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 9

continua …// alloca, visualizza e successivamente rilascia, buffer per// un numero di valori interi specificato a run-timeint main() { // definisce le variabili per il numero dei valori interi e per // l’indirizzo iniziale del buffer size_t nro_val; int *ptr; // inizializza la variabile per il numero di valori printf("\nQuanti valori? "); scanf("%u", &nro_val); // alloca memoria per il buffer ptr = (int*) malloc(nro_val * sizeof(int));

continua …

Page 10: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni malloc() e free()Le funzioni malloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 10

continua … // se l’allocazione e’ fallita termina if (ptr == NULL) { printf("\nAllocazione fallita"); return(0); }; // se l'allocazione è avvenuta con successo visualizza il contenuto // del buffer e rilascia la memoria per questo allocata printf("\nAllocazione avvenuta con successo\n"); printf(“\nContenuto del buffer: “); VisBuffInt(ptr, nro_val); free(ptr); return(1); }

Page 11: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni malloc() e free()Le funzioni malloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 11

• Compilazione:

• Esecuzione:

• Esecuzione:

Il buffer non viene inizializzat

o

Page 12: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione calloc()La funzione calloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 12

• Signature:

void *calloc(size_t nro_var, size_t dim_var);

• Modifiche allo stato della memoria:

alloca un buffer di memoria per nro_var variabili di dimensione dim_var, e le inizializza a 0

• Valore restituito:

- l’indirizzo del primo byte del buffer, in caso di successo

- il valore NULL altrimenti

Page 13: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni calloc() e free()Le funzioni calloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 13

// sorgente: Lezione_XVI\calloc.c// illustra il corretto utilizzo dalla funzione calloc() e della free()// inclusione del file di intestazione della libreria standard che// contiene definizioni di macro, costanti e dichiarazioni di funzioni// e tipi funzionali alle varie operazioni di I/O#include <stdio.h>// inclusione del file di intestazione della libreria standard che// contiene definizioni di macro, costanti e dichiarazioni di funzioni// di interesse generale#include <stdlib.h>// visualizza il contenuto di un buffer di interivoid VisBuffInt(int *ptr, size_t dim) { // definisce la variabile necessaria a muoversi sul buffer size_t curs; // attraversa il buffer visualizzandone il contenuto for (curs = 0; curs <= dim-1; curs++) printf("\n%d", ptr[curs]); };

continua …

Page 14: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni calloc() e free()Le funzioni calloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 14

continua …// alloca, visualizza e successivamente rilascia, un buffer per// un numero di valori interi specificato a run-timeint main() { // definisce le variabili per il numero dei valori interi e per // l’indirizzo iniziale del buffer size_t nro_val; int *ptr; // inizializza la variabile per il numero di valori printf("\nQuanti valori? "); scanf("%u", &nro_val); // alloca e inizializza la memoria per il buffer ptr = (int*) calloc(nro_val, sizeof(int));

continua …

Page 15: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni calloc() e free()Le funzioni calloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 15

continua … // se l’allocazione e’ fallita termina if (ptr == NULL) { printf("\nAllocazione fallita"); return(0) }; // se l'allocazione ha avuto successo visualizza il contenuto del // buffer e successivamente libera la memoria per questo allocata printf("\nAllocazione avvenuta con successo\n"); printf("\nContenuto del buffer:"); VisBuffIn(ptr, nro_val); free(ptr); return(1); }

Page 16: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni calloc() e free()Le funzioni calloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 16

• Compilazione:

• Esecuzione:

• Esecuzione:

Il buffer è inizializzato

a 0

Page 17: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione realloc()La funzione realloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 17

• Signature:

void *realloc(void * ptr, size_t size);• Modifiche allo stato della memoria:

estende, o nel caso comprime, il buffer riferito da ptr, mantenendo inalterato il contenuto della porzione preesistente, a meno di troncamenti. Gestisce automaticamente eventuali ricollocazioni del buffer.

• Valore restituito:- l’indirizzo del primo byte del buffer, in

caso di successo- il valore NULL altrimenti

• realloc(NULL, size):

equivale a malloc(size)

Page 18: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

void *ptr = realloc(NULL, 5);ptr = realloc(ptr, 8);…free(ptr);

NULL

La funzione realloc() e i La funzione realloc() e i memory leakmemory leak

Programmazione di Calcolatori: i vettori 18

• Memory leak:

area di memoria allocata e non più accessibile non esistendo puntatori che la riferiscono

100

ptr

xx

xx

x

099100101102103104105

NULL

Non ha alcun effetto

Page 19: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione realloc()La funzione realloc()

Programmazione di Calcolatori: i vettori 19

ptr

void *ptr , *tmp;ptr = realloc(NULL, 2);tmp = realloc(ptr, 4);// gestione dell’erroreif (tmp == NULL){printf (“errore”);free(ptr);return (0);}elseptr = tmp;….free(ptr);

tmp

099100101102103104105106107

x

x

xx

100

xx

xx

103

103

• L’approccio corretto:

Page 20: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione realloc()La funzione realloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 20

// sorgente: Lezione_XVI\realloc.c// illustra il corretto utilizzo dalla funzione realloc()// inclusione del file di intestazione della libreria standard che// contiene definizioni di macro, costanti e dichiarazioni di funzioni// e tipi funzionali alle varie operazioni di I/O#include <stdio.h>// inclusione del file di intestazione della libreria standard che// contiene definizioni di macro, costanti e dichiarazioni di funzioni// di interesse generale#include <stdlib.h>// inizializza il contenuto di un buffer di interi con una sequenza// progressiva di interivoid InBuffInt(int *ptr, size_t dim) { // definisce la variabile necessaria a muoversi sul buffer size_t curs; // attraversa il buffer visualizzandone il contenuto for (curs = 0; curs <= dim-1; curs++) ptr[curs] = curs; }; continua …

Page 21: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione realloc()La funzione realloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 21

continua …// visualizza il contenuto di un buffer di interivoid VisBuffInt(int *ptr, size_t dim) { // definisce la variabile necessaria a muoversi sul buffer size_t curs; // attraversa il buffer visualizzandone il contenuto for (curs = 0; curs <= dim-1; curs++) printf("\n%d", ptr[curs]); };// alloca, visualizza, ridimensiona, visualizza nuovamente e rilascia, un// buffer per un numero di valori interi specificato a run-timeint main() { // definisce le variabili per il numero dei valori interi e per // il riferimento al buffer iniziale size_t nro_val; int *ptr; continua …

Page 22: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione realloc()La funzione realloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 22

continua … // definisce una variabile temporanea per il riferimento al buffer // ridimensionato, al fine di non perdere il riferimento al buffer // iniziale se il ridimensionamento fallisse int *tmp; // definisce una variabile per il numero di valori interi nel buffer // ridimensionato size_t new_nro_val; // inizializza la variabile per il numero di valori nel buffer iniziale printf("\nQuanti valori nel buffer iniziale? "); scanf("%u", &nro_val); // alloca memoria per il buffer iniziale ptr = (int *) realloc(NULL, nro_val*sizeof(int)); // se l’allocazione è fallita termina if (ptr == NULL) { printf("\nAllocazione fallita"); return(0); }; continua …

Page 23: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione realloc()La funzione realloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 23

continua … // altrimenti, se l'allocazione ha avuto successo, inizializza e // visualizza il buffer iniziale printf("\nAllocazione avvenuta con successo\n"); InBuffInt(ptr, nro_val); printf("\nBuffer iniziale:\n"); VisBuffInt(ptr, nro_val); // inizializza la variabile per il numero di valori nel buffer // ridimensionato printf("\nQuanti valori nel buffer ridimensionato? "); scanf("%u", &new_nro_val); // ridimensiona il buffer iniziale tmp = (int *)realloc(ptr, new_nro_val); // verifica se il ridimensionamento è avvenuto con successo if (tmp == NULL) { // se il ridimensionamento e' fallito visualizza il buffer originale // e termina printf("\nAllocazione fallita”); printf("\nBuffer iniziale:\n "); VisBuffInt(ptr, nro_val); }; continua …

Page 24: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione realloc()La funzione realloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 24

continua … // se il ridimensionamento e’ avvenuto con successo // aggiorna il riferimento al buffer ptr = tmp; // visualizza il contenuto del buffer ridimensionato printf("\nAllocazione avvenuta con successo”); printf("\nBuffer ridimensionato:"); VisBuffInt(ptr, new_nro_val); // rilascia la memoria allocata per il buffer free(ptr); return(1); }

Page 25: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione realloc()La funzione realloc()

Programmazione di Calcolatori: allocazione dinamica della memoria 25

• Compilazione:

• Esecuzione:

Page 26: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso La funzione realloc() e La funzione realloc() e free()free()

Programmazione di Calcolatori: allocazione dinamica della memoria 26

• Esecuzione:

Page 27: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

Le funzioni calloc() e free()Le funzioni calloc() e free()

Programmazione di Calcolatori: allocazione dinamica della memoria 27

• Esecuzione:

Page 28: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione memcpy()La funzione memcpy()

Programmazione di Calcolatori: allocazione dinamica della memoria 28

• Signature:void * memcpy(void * dest, void * src, int n)

• Modifiche allo stato della memoria:copia n byte dall’indirizzo src all’indirizzo dst

• Valore restituito:l’indirizzo dest

• Direttive per il preprocessore:includere la direttiva #include <string.h> per utilizzare la funzione

Page 29: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione memcpy()La funzione memcpy()

Programmazione di Calcolatori: allocazione dinamica della memoria 29

// sorgente: Lezione_XVI\memcpy.c// illustra il corretto utilizzo dalla funzione memcpy()// inclusione del file di intestazione della libreria standard// che contiene definizioni di macro, costanti e dichiarazioni// di funzioni e tipi funzionali alle varie operazioni di I/O#include <stdio.h>// inclusione del file di intestazione della libreria standard che// contiene definizioni di macro,costanti e dichiarazioni di funzioni di// interesse generale, per la gestione della memoria e delle stringhe#include <stdlib.h>#include <string.h> // inizializza il contenuto di un buffer di interi con una sequenza pro-// gressiva di interivoid InBuffInt(int *ptr, size_t dim) { // definisce la variabile necessaria a muoversi sul buffer size_t curs; // attraversa il buffer visualizzandone il contenuto for (curs = 0; curs <= dim-1; curs++) ptr[curs] = curs; }; continua …

Page 30: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione memcpy()La funzione memcpy()

Programmazione di Calcolatori: allocazione dinamica della memoria 30

continua …// visualizza il contenuto di un buffer di interivoid VisBuffInt(int *ptr, size_t dim) { // definisce la variabile necessaria a muoversi sul buffer size_t curs; // attraversa il buffer visualizzandone il contenuto for (curs = 0; curs <= dim-1; curs++) printf("\n%d", ptr[curs]); };// alloca due buffer di interi, inizializza il I, lo visualizza e lo copia nel II.// Visualizza il contenuto del II e rilascia tutta la memoria allocata int main() { // definisce le variabili per il numero dei valori interi e per i // riferimenti ai due buffer size_t nro_val; int *ptr_1, *ptr_2; // inizializza la variabile per il numero di valori in entrambe i buffer printf("\nQuanti valori nei buffer? "); scanf("%u", &nro_val);

continua …

Page 31: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione memcpy()La funzione memcpy()

Programmazione di Calcolatori: allocazione dinamica della memoria 31

continua … // alloca memoria per i due buffer ptr_1 = (int *) realloc(NULL,nro_val*sizeof(int)); ptr_2 = (int *) realloc(NULL,nro_val*sizeof(int)); // controlla se l’allocazione è avvenuta con successo if ((ptr_1 == NULL) || (ptr_2 == NULL)) { // se l’allocazione è fallita rilascia la memoria allocata // e termina printf("\nAllocazione fallita"); if (ptr_1 != NULL) free(ptr_1); if (ptr_2 != NULL) free(ptr_1); return(0); }; // altrimenti inizializza il I buffer e lo visualizza printf("\nAllocazione avvenuta con successo\n"); InBuffInt(ptr_1, nro_val); printf("\nContenuto I Buffer:"); VisBuffInt(ptr_1, nro_val);

continua …

Page 32: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione memcpy()La funzione memcpy()

Programmazione di Calcolatori: allocazione dinamica della memoria 32

continua … // copia il I buffer nel II e lo visualizza ptr_2 = memcpy(ptr_2, ptr_1, nro_val*sizeof(int)); printf("\nContenuto II Buffer:"); VisBuffInt(ptr_2, nro_val); // rilascia la memoria per entrambe i buffer free(ptr_1); free(ptr_2); return(1); }

Page 33: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione memcpy()La funzione memcpy()

Programmazione di Calcolatori: allocazione dinamica della memoria 33

• Compilazione:

• Esecuzione:

Page 34: C. Gaibisso Programmazione di Calcolatori Lezione XVI Allocazione dinamica della memoria Programmazione di Calcolatori: allocazione dinamica della memoria.

C. Gaibisso

La funzione memcpy()La funzione memcpy()

Programmazione di Calcolatori: allocazione dinamica della memoria 34

• Esecuzione: