La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Gestione della memoria

Presentazioni simili


Presentazione sul tema: "Gestione della memoria"— Transcript della presentazione:

1 Gestione della memoria
Il linguaggio C Gestione della memoria Moreno Marzolla Dipartimento di Informatica—Scienza e Ingegneria (DISI) Università di Bologna

2 Linguaggio C - Gestione della memoria
Copyright © Mirko Viroli Copyright © 2017, Moreno Marzolla This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) License. To view a copy of this license, visit or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San Francisco, California, 94105, USA. Linguaggio C - Gestione della memoria

3 Linguaggio C - Gestione della memoria
Ringraziamenti Questi lucidi si basano su materiale fornito dal prof. Mirko Viroli, Università di Bologna Linguaggio C - Gestione della memoria

4 Linguaggio C - Gestione della memoria
Puntatore a puntatore Si può definire un puntatore ad una zona di memoria che contiene a sua volta un puntatore /* punt-punt.c : esempio di puntatore a puntatore */ #include <stdio.h> int main( void ) { int a = 10; int *pa = &a; int **ppa = &pa; printf("a=%d, pa=%p\n", a, (void*)pa); printf("ppa=%p, *ppa=%p, **ppa=%d\n", (void*)ppa, (void*)*ppa, **ppa); return 0; } a 10 pa ppa a=10, pa=0x7fff3fcd849c ppa=0x7fff3fcd84a0, *ppa=0x7fff3fcd849c, **ppa=10 Linguaggio C - Gestione della memoria Memoria

5 Linguaggio C - Gestione della memoria
/* punt-punt2.c */ #include <stdio.h> int main( void ) { int a0[2] = {1, 2}; int a1[2] = {3, 4}; int *ap[2]; int **pp = ap; ap[0] = a0; ap[1] = a1; printf("pp[0][0]: %d\n", pp[0][0]); /* stampa 1 */ printf("pp[0][1]: %d\n", pp[0][1]); /* stampa 2 */ printf("pp[1][0]: %d\n", pp[1][0]); /* stampa 3 */ printf("pp[1][1]: %d\n", pp[1][1]); /* stampa 4 */ printf("**pp: %d\n", **pp); /* stampa 1 */ printf("*(*pp+1): %d\n", *(*pp+1)); /* stampa 2 */ printf("**(pp+1): %d\n", **(pp+1)); /* stampa 3 */ printf("*(*(pp+1)+1): %d\n", *(*(pp+1)+1)); /* stampa 4 */ return 0; } pp ap[] a0[] a1[] 1 2 3 4 Memoria Linguaggio C - Gestione della memoria

6 Linguaggio C - Gestione della memoria
**pp pp 1 2 3 4 *pp 1 2 3 4 **pp 1 2 3 4 Linguaggio C - Gestione della memoria

7 Linguaggio C - Gestione della memoria
*(*pp + 1) *pp 1 2 3 4 *pp + 1 1 2 3 4 *(*pp+1) 1 2 3 4 Linguaggio C - Gestione della memoria

8 Linguaggio C - Gestione della memoria
**(pp + 1) pp 1 2 3 4 pp+1 1 2 3 4 *(pp+1) 1 2 3 4 **(pp+1) 1 2 3 4 Linguaggio C - Gestione della memoria

9 Linguaggio C - Gestione della memoria
*(*(pp+1)+1) pp+1 pp 1 2 3 4 *(pp+1) 1 2 3 4 *(pp+1)+1 1 2 3 4 *(*(pp+1)+1) 1 2 3 4 Linguaggio C - Gestione della memoria

10 Linguaggio C - Gestione della memoria
Puntatori a puntatori Sono utili per gestire array di stringhe di caratteri /* es-array-str.c : Esempio di array di stringhe */ #include <stdio.h> int main( void ) { char *parole[] = {"Ciao", "come", "stai?", NULL}; int i; for (i=0; parole[i] != NULL; i++) { printf("%s ", parole[i]); } printf("\n"); return 0; X parole[] Ciao\0 come\0 stai?\0 Memoria Linguaggio C - Gestione della memoria

11 Linguaggio C - Gestione della memoria
Array di stringhe In realtà la funzione main() accetta un intero e un array di stringhe Il sistema operativo li setta al numero di argomenti sulla riga di comando, e le stringhe che rappresentano tali argomenti $ ./main-param uno due tre -3 parametro 0: ./main-param parametro 1: uno parametro 2: due parametro 3: tre parametro 4: -3 /* main-param.c : Esempio di array di stringhe */ #include <stdio.h> int main( int argc, char* argv[] ) { int i; for (i=0; i < argc; i++) { printf("parametro %d: %s\n", i, argv[i]); } return 0; Linguaggio C - Gestione della memoria

12 Linguaggio C - Gestione della memoria
La funzione malloc() Definita in stdlib.h Serve per allocare (riservare) una porzione di memoria da usare per memorizzare qualunque dato Si passa come parametro la dimensione (in byte) richiesta malloc()ritorna un puntatore void * che deve essere convertito (con un cast) al puntatore di tipo richiesto La memoria va liberata quando non serve più con free() Con malloc() è possibile creare array la cui dimensione non è nota a priori Consente anche di realizzare funzioni che creano array e li restituiscono come risultato Linguaggio C - Gestione della memoria

13 Linguaggio C - Gestione della memoria
Esempio /* reverse-fun.c : esempio di funzione che ritorna un array */ #include <stdio.h> #include <stdlib.h> /* Dato un array a[] di n elementi, restituisce un nuovo array di n elementi il cui contenuto e' il contenuto di a[] "a rovescia" */ int *reverse(int a[], int n) { int *r = (int *)malloc(n*sizeof(int)); int i; for (i=0; i<n; i++){ r[i]=a[n-1-i]; } return r; int main( void ) int in[] = {10, 20, 30, 40}; int *out = reverse(in, 4); printf("%d %d %d %d\n", out[0], out[1], out[2], out[3]); free(out); return 0; Linguaggio C - Gestione della memoria

14 La libreria <string.h>
Contiene varie funzioni per manipolare stringhe Si ricordi che la stringa “prova” è un array di 6 caratteri, 'p' 'r' 'o' 'v' 'a' '\0' Linguaggio C - Gestione della memoria

15 Alcune funzioni di <string.h>
size_t strlen(const char *s); Restituisce la lunghezza (numero di caratteri) di s int strcmp(const char *s1, const char *s2); Ritorna un valore minore, maggiore, uguale a 0 se s1 è "minore", "maggiore", "uguale a" s2 Si usa l'ordinamento lessicografico tra stringhe char *strcpy(char *dest, const char *src); Copia il contenuto di src in dest dest deve puntare ad una area di memoria già allocata, sufficientemente capiente restituisce un puntatore a dest char *strcat(char *dest, const char *src); Appende la stringa src alla fine di dest Linguaggio C - Gestione della memoria

16 Linguaggio C - Gestione della memoria
Esempio riassuntivo Lunghezza di "Prova" e' 5 Lunghezza di "Casa" e' 4 Copia di "Prova" su c3; c3 diventa: "Prova" Concatena "Casa" a c3: "ProvaCasa" Confronto "Prova" e "Prova": 0 Confronto "Prova" e "Casa": 13 Confronto "Casa" e "Prova": -13 /* demo-string.c */ #include <stdio.h> #include <string.h> int main( void ) { char c1[] = "Prova"; char c2[] = "Casa"; char c3[100]; printf("Lunghezza di \"%s\" e' %d\n", c1, (int)strlen(c1)); printf("Lunghezza di \"%s\" e' %d\n", c2, (int)strlen(c2)); strcpy(c3,c1); printf("Copia di \"%s\" su c3; c3 diventa: \"%s\"\n", c1, c3); strcat(c3,c2); printf("Concatena \"%s\" a c3: \"%s\"\n", c2, c3); printf("Confronto \"%s\" e \"%s\": %d\n", c1, c1, strcmp(c1, c1)); printf("Confronto \"%s\" e \"%s\": %d\n", c1, c2, strcmp(c1, c2)); printf("Confronto \"%s\" e \"%s\": %d\n", c2, c1, strcmp(c2, c1)); return 0; } Linguaggio C - Gestione della memoria

17 Attenzione all'allocazione
Le funzioni strcat() e strcpy() vanno a copiare dei caratteri da una stringa src ad una dest Bisogna fare attenzione ad accertarsi che nel fare ciò non si esca dai limiti consentiti per dest, rischiando di sovrascrivere memoria altrui P r o v a \0 ? ? ? ? #include <stdio.h> #include <string.h> int main( void ) { char s1[10] = "Prova"; char s2[] = "Riprova"; strcat(s1, s2); /* No! Non c'e' abbastanza spazio in s1[] */ printf("Risultato della concatenazione: \"%s\"\n", s1); return 0; } R i p r o v a \0 Linguaggio C - Gestione della memoria


Scaricare ppt "Gestione della memoria"

Presentazioni simili


Annunci Google