Introduzione al C Lez. 4

Documenti analoghi
Introduzione al C Lez. 4. Allocazione Dinamica della memoria

Introduzione al C Lez. 5. Stringhe

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

Allocazione dinamica della memoria

Uso avanzato dei puntatori Allocazione dinamica della memoria

Gestione dinamica della memoria

Il linguaggio C. Puntatori e dintorni

Lezione 12: Allocazione Dinamica della Memoria

L'Allocazione Dinamica della Memoria nel linguaggio C

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

Corso di Informatica A.A

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

Lezione 8: Stringhe ed array multidimensionali

char *s; s = (char *) malloc(5*sizeof(char)); scanf( %s, s); Stringhe

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

Allocazione dinamica della memoria

Introduzione al C Lez. 3. Puntatori

C: panoramica. Violetta Lonati

Liste concatenate e allocazione dinamica

Puntatori. Operazioni sui puntatori Allocazione dinamica

puntatori Lab. Calc. AA 2006/07 1

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

Puntatori. Grazie ai puntatori:

L Allocazione Dinamica della Memoria

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

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

Lezione IX Gestione dinamica della memoria

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

La gestione della memoria dinamica Heap

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

Il linguaggio C. Puntatori e dintorni

Lezione IX Gestione dinamica della memoria

Allocazione Dinamica della Memoria

Introduzione al linguaggio C Puntatori

Array. Aggragati di variabili omogenee...

Allocazione dinamica della memoria

Laboratorio di Informatica I

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

Definizione Allocazione e deallocazione di variabili Allocazione e deallocazione di vettori

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

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

Strutture Dati Dinamiche

L'allocazione dinamica della memoria

L'allocazione dinamica della memoria

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

Corso di Informatica A.A

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

Esercitazione di Reti degli elaboratori

Laboratorio di Informatica I

Lezione 6: Array e puntatori

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

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

Lezione 19 e Allocazione dinamica della memoria - Direttive al preprocessore - Libreria standard - Gestione delle stringhe

Liste concatenate e allocazione dinamica

Allocazione dinamica. VLA, malloc() e dintorni

Lezione 8 Struct e qsort

Introduzione al linguaggio C Puntatori

Puntatori e array. Violetta Lonati

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

Introduzione al C. Unità Gestione Dinamica della Memoria

Linguaggio C. Vettori, Puntatori e Funzioni Stringhe. Università degli Studi di Brescia. Prof. Massimiliano Giacomin

Caratteri e stringhe

ALGORITMI E STRUTTURE DATI

Unità 11 Allocazione dinamica

L apertura di un file ci restituisce un puntatore a una struttura chiamata FILE fopen:

Lezione 6 Selection/Insertion Sort su interi e stringhe

Introduzione al C. Lezione 1 Elementi. Rossano Venturini. Pagina web del corso

Esercizi Programmazione I

Lezione 6 Struct e qsort

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

Stringhe in C. Alessandra Giordani Lunedì 23 aprile 2012

Lezione 3 Sottoarray di somma massima

Lezione 3 Sottoarray di somma massima

Lezione 5 Sottoarray di somma massima

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

Stringhe e allocazione dinamica della memoria

Introduzione al C. Lez. 2 Funzioni e Puntatori

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

Gli array. slides credit M. Poneti

Stringhe in C. Luca Abeni. Informatica Luca Abeni 1 / 10

Allocazione statica della memoria

Linguaggio C: Stringhe Valeria Cardellini

Le stringhe. Le stringhe sono sequenze di caratteri,

Il linguaggio C Gestione della memoria

Gestione della memoria

FUNZIONI. attribuire un nome ad un insieme di istruzioni parametrizzare l esecuzione del codice

Lab 11 Allocazione dinamica della memoria

Fondamenti di Informatica 2

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

Esercizio 1. Programmazione I e Informatica II

Corso Programmazione

Lab 12 Allocazione dinamica della memoria

Transcript:

Introduzione al C Lez. 4 Allocazione Dinamica della memoria http://www.di.unipi.it/~rossano/algo1/lez4.pdf

Allocazione dinamica memoria In C la memoria può essere anche gestita in modo dinamico, attraverso l allocazione esplicita di blocchi di memoria di data dimensione. A cosa serve? - Ad allocare array la cui dimensione non è nota a tempo di compilazione ma calcolata a tempo di esecuzione - Per gestire strutture dati che crescono e decrescono durante l'esecuzione del programma (ad esempio liste) - Per avere maggiore flessibilità sulla durata della memoria allocata. (Altrimenti la memoria verrà deallocata all'uscita del blocco nel quale è stata allocata.)

Allocazione dinamica memoria Esempio. Leggere da input un intero n e creare un array di n interi int n; scanf( %d, &n); int a[n]; // ERRORE! Non è consentito in ANSI C! Il numero di elementi di un array deve essere noto a tempo di compilazione. Quindi, deve essere una costante e non una variabile.

Allocazione dinamica memoria - i blocchi sono allocati tipicamente in una parte della memoria chiamata heap; - è possibile accedere a tali blocchi di memoria attraverso l uso di puntatori; - lo spazio allocato dinamicamente NON viene liberato all uscita delle funzioni; - sempre con l uso di puntatori la memoria che non serve più va deallocata in modo da renderla nuovamente disponibile.

Allocazione dinamica memoria - i blocchi sono allocati tipicamente in una parte della memoria chiamata heap; - è possibile accedere a tali blocchi di memoria attraverso l uso di puntatori; - lo spazio allocato dinamicamente NON viene liberato all uscita delle funzioni; - sempre con l uso di puntatori la memoria che non serve più va deallocata in modo da renderla nuovamente disponibile. Come si fa? - Tre funzioni malloc, calloc e realloc ci permettono di allocare memoria dinamicamente.

Malloc Definita in stdlib.h. Includetelo! #include <stdlib.h> void * malloc(size_t size) - dove size specifica la lunghezza in byte del blocco allocato. size_t è un tipo definito in stdlib.h. (In genere è un unsigned int.)

Malloc Definita in stdlib.h. Includetelo! #include <stdlib.h> void * malloc(size_t size) - dove size specifica la lunghezza in byte del blocco allocato. size_t è un tipo definito in stdlib.h. (In genere è un unsigned int.) - La funzione restituisce un puntatore al primo byte del blocco allocato. (void è un tipo generico). Con un assegnamento il tipo del puntatore viene convertito implicitamente. int *p = malloc( 10 * sizeof(int) )

Malloc Definita in stdlib.h. Includetelo! #include <stdlib.h> void * malloc(size_t size) - dove size specifica la lunghezza in byte del blocco allocato. size_t è un tipo definito in stdlib.h. (In genere è un unsigned int.) - La funzione restituisce un puntatore al primo byte del blocco allocato. (void è un tipo generico). Con un assegnamento il tipo del puntatore viene convertito implicitamente. int *p = malloc( 10 * sizeof(int) ) - Se non è possibile allocare memoria (ad es. è esaurita), la funzione restituisce il puntatore NULL (un altro modo per dire 0 :-)). Controllarlo. Sempre!

Malloc Esempio #include <stdlib.h> int i, n, *p; scanf( %d, &n); p = malloc(n * sizeof(int)); //alloca spazio per n interi if (p == NULL) { // controlliamo printf( Non posso allocare %d interi\n,100); exit(1); // esce con un errore }

Malloc Esempio #include <stdlib.h> int i, n, *p; scanf( %d, &n); p = malloc(n * sizeof(int)); //alloca spazio per n interi if (p == NULL) { // controlliamo printf( Non posso allocare %d interi\n,100); exit(1); // esce con un errore } // se sono arrivato qui posso usare il blocco allocato for(i = 0; i < n; i++) // qui mettiamo i primi n interi p[i] = i; Attenzione! Non si può accedere ad indirizzi fuori dallo spazio allocato. p[n] NO! Segmentation fault

Calloc Definita in stdlib.h. Includetelo! void * calloc(size_t nmemb, size_t size) - simile alla malloc ma gli elementi sono inizializzati a 0. - nmemb indica il numero di elementi nell'array mentre size specifica la lunghezza in byte di ciascun elemento.

Calloc Definita in stdlib.h. Includetelo! void * calloc(size_t nmemb, size_t size) - simile alla malloc ma gli elementi sono inizializzati a 0. - nmemb indica il numero di elementi nell'array mentre size specifica la lunghezza in byte di ciascun elemento. Esempio Scrivere calloc usando la malloc

Calloc Definita in stdlib.h. Includetelo! void * calloc(size_t nmemb, size_t size) - simile alla malloc ma gli elementi sono inizializzati a 0. - nmemb indica il numero di elementi nell'array mentre size specifica la lunghezza in byte di ciascun elemento. Esempio Scrivere calloc usando la malloc void * my_calloc(size_t nmemb, size_t size) { size_t i; char *p = malloc( nmemb * size ); if (p == NULL) return NULL for (i = 0; i < nmemb*size; i++) *(p+i) = 0; return p; }

Liberare la memoria Quando un blocco di memoria non serve più è importante deallocarlo e renderlo nuovamente disponibile utilizzando la funzione void free(void *) L'argomento di free deve essere allocato precedentemente (o NULL) altrimenti il comportamento è indefinito.

Esercizio 1 Scrivere una funzione void minmax(int a[], int len, int *min, int *max) che, dato un array a e la sua lunghezza len, scriva il valore del massimo e del minimo elemento negli indirizzi puntati dalle variabili min e max. Scrivere un programma che legga da tastiera un intero n e utilizzi rand() per la generazione di un array di n elementi interi casuali e provare la funzione. Ricordarsi di liberare la memoria.

Esercizio 2 Input: Leggere da tastiera una sequenza di interi. Il primo di questi indica quanti interi compongono la sequenza. Output: m x\n dove m è la media degli interi e x è il numero di interi uguali a m. Esempio 4 7 7 4 10 7 2

Stringhe Una stringa è una sequenza di caratteri. Ad esempio una parola, una frase, un testo In C non è previsto un tipo per le stringhe. Una stringa è vista come un array di caratteri che, per convenzione, termina con il simbolo speciale '\0'. Si usa char s[n+1]; per memorizzare una stringa di N caratteri.

Stringhe Le costanti stringa vengono rapresentate tra virgolette. Esempio ciao è un array di caratteri di dimensione 5. c i a o \0

Stringhe Le costanti stringa vengono rapresentate tra virgolette. Esempio ciao è un array di caratteri di dimensione 5. c i a o \0 Una costante stringa viene trattata come un puntatore al primo carattere della stringa. Esempio char *s = ciao ; // anche char s[] = ciao ; s qui è costante print( %s %s\n, s, s+1);// stampa ciascun carattere fino a '\0' print( %c %c\n, s[0], s[1]); Cosa stampa?

Stringhe Le costanti stringa vengono rapresentate tra virgolette. Esempio ciao è un array di caratteri di dimensione 5. c i a o \0 Una costante stringa viene trattata come un puntatore al primo carattere della stringa. Esempio char *s = ciao ; // anche char s[] = ciao ; s qui è costante print( %s %s\n, s, s+1);// stampa ciascun carattere fino a '\0' print( %c %c\n, s[0], s[1]); Cosa stampa? ciao iao c i Nota: la stdlib contiene molte funzioni per gestire stringhe.

Stringhe Esempio void my_printf(char *s) { } int i = 0; while(s[i]) // s[i] == 0 printf( %c, s[i++]); int main() { } char s[101]; // stringhe fino a 100 caratteri scanf( %s, s); my_printf(s); return 0;

Stringhe Alternativa void my_printf(char *s) { } while(*s) printf( %c, *s++); // è s ad essere incrementato int main() { } char s[101]; // stringhe fino a 100 caratteri scanf( %s, s); my_printf(s); return 0;

Stringhe Ovviamente potete allocare dinamicamente memoria per contenere una stringa. char * s = malloc((n+1)*sizeof(char)); if(!s) exit(1);

Array Bidimensionali Una matrice che ha N righe ed M colonne int a[n][m]; 1 0 0 1 2 M-1 N-1

Array Bidimensionali Una matrice che ha N righe ed M colonne int a[n][m]; Si può utilizzare a[i][j] per accedere all'elemento in riga i colonna j. 1 0 0 1 2 M-1 N-1

Array Bidimensionali Una matrice che ha N righe ed M colonne int a[n][m]; Si può utilizzare a[i][j] per accedere all'elemento in riga i colonna j. Si può passare un array bidimensionale ad una funzione ma si deve specificare la lunghezza della seconda componente nella dichiarazione della funzione! Esempio void foo(int a[][5], int righe); 1 0 N-1 0 1 2 M-1

Array Bidimensionali Una matrice che ha N righe ed M colonne int a[n][m]; Si può utilizzare a[i][j] per accedere all'elemento in riga i colonna j. Si può passare un array bidimensionale ad una funzione ma si deve specificare la lunghezza della seconda componente nella dichiarazione della funzione! Esempio void foo(int a[][5], int righe); Questa funzione opererà solo con matrici aventi 5 colonne. Forte limitazione! Si possono rimpiazzare con array classici calcolando opportunamente gli indici. 1 0 N-1 0 1 2 M-1

Array Bidimensionali Esempio. Calcolo della somma degli elementi in una matrice N x 5 int sum(int a[][5], int righe) { int i, j, sum = 0; for( i = 0; i < righe; i++ ) for ( j = 0; j < 5; j++ ) sum += a[i][j]; return sum; } 0 1 2 3 4 N-1 1 0

Esercizio 3 Scrivere la funzione int my_strlen(char *s) che restituisce il numero di caratteri della stringa s. Scrivere un programma che provi questa funzione leggendo una stringa da tastiera. Si può assumere che la stringa in input contenga non più di 1000 caratteri. Strumenti utili: Si può leggere leggere una stringa da tastiera con char str[1001]; scanf( %s, str);

Esercizio 4 Scrivere la funzione char * my_strcat(char *s1, char *s2) che restituisce un puntatore alla nuova stringa ottenuta concatenando le stringhe puntate da s1 e s2. Scrivere un programma che legga due stringhe da tastiera e stampando la stringa e stampi la contatenazione delle due. Si può assumere che le stringhe in input contengano non più di 1000 caratteri. Notare che il comportamento di my_strcat() è diverso da quello della funzione strcat() presente nella libreria stdlib.

Esercizio 5 Scrivere un programma che legga una stringa da tastiera e stampi uno tra i bigrammi più frequenti contenuti in tale stringa e la sua frequenza. Bigramma = coppia di caratteri consecutivi Usare una matrice bidimensionale 256x256 dove memorizzare le frequenze dei bigrammi. Assumere che la stringa in input consista di al più 1000 caratteri. Esempio: pazzapezzapizzapozzapuzza zz e za sono i bigrammi più frequenti. Il programma deve stampare uno di questi e la sua frequenza 5 Nota: il tipo char è con segno. Usare unsigned char.

Altri esercizi Ripetere gli esercizi 1 e 2 della seconda lezione ( http://www.di.unipi.it/~aorlandi/algo/es2.pdf ) rimuovendo l'assunzione sul valore massimo di n.