appunti3s:gestione_della_memoria
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
appunti3s:gestione_della_memoria [2019/06/29 13:51] – profpro | appunti3s:gestione_della_memoria [2023/10/02 09:54] (current) – profpro | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | > Per ;;tornare all' | ||
+ | ====== Gestione della memoria ====== | ||
+ | |||
+ | ===== Introduzione ===== | ||
+ | |||
+ | A seconda di come e dove vengono definite, si possono avere diversi tipi di variabili: | ||
+ | * variabili globali: definite fuori da ogni funzione (anche dal main) o classe | ||
+ | * variabili locali (o automatiche): | ||
+ | * variabili statiche: per approfondimento vedere [[appunti3s: | ||
+ | * variabili dinamiche: termine usato per definire l' | ||
+ | |||
+ | ===== Risorsa memoria ===== | ||
+ | Un programma contiene istruzioni da eseguire. | ||
+ | Un programma in esecuzione sul sistema operativo viene chiamato // | ||
+ | Il file eseguibile, prima dell' | ||
+ | Nella memoria centrale il file eseguibile è diviso in diverse sezioni (section): text section, data setion e stack section. | ||
+ | Il sistema operativo può gestire ogni sezione, dividendola ulteriormente in segmenti (segment) (anche non contigui tra loro). | ||
+ | Tutto ciò è necessario perché un sistema operativo multitasking, | ||
+ | |||
+ | {{: | ||
+ | ==== Segment ==== | ||
+ | Un segmento rappresenta un' | ||
+ | |||
+ | ==== Text segment ==== | ||
+ | Area che contiene le istruzioni eseguibili e le costanti. Durante l' | ||
+ | |||
+ | ==== Data segment ==== | ||
+ | Area che contiene le variabili cosiddette // | ||
+ | |||
+ | ====BBS segment ==== | ||
+ | (Block Started by Symbol) area che contiene le variabili cosiddette //globali// e quelle // | ||
+ | |||
+ | ==== Heap segment ==== | ||
+ | {{ : | ||
+ | Nel linguaggio C++ questa memoria è riservata e liberata con una gestione manuale (operatore new e operatore delete). | ||
+ | Nel linguaggio JAva l' | ||
+ | |||
+ | ==== Stack ==== | ||
+ | {{ : | ||
+ | |||
+ | ==== Confronto delle caratteristiche ==== | ||
+ | |||
+ | Una variabile //locale// (nello stack) ha una vita pari a quella del periodo di esecuzione della funzione. Una variabile allocata dinamicamente (nell' | ||
+ | |||
+ | Quando non interviene il programmatore: | ||
+ | * Le variabili globali, statiche e gli oggetti sono inizializzati automaticamente a zero. | ||
+ | * Rimangono non inizializzate le altre variabili, cioè: | ||
+ | * quelle locali (allocate nello stack) | ||
+ | * quelle dinamiche (allocate con //new// nell' | ||
+ | |||
+ | ====== Puntatori a... (qualcosa) ====== | ||
+ | Prima di spiegare i puntatori è necessario ricordare la distinzione tra la cosiddetta memoria automatica e memoria dinamica. | ||
+ | |||
+ | * **Memoria automatica** Le variabili automatiche (cosiddette locali) sono gestite automaticamente nello //stack// e quando non servono più vengono automaticamente " | ||
+ | * **Memoria dinamica** Durante l' | ||
+ | Per riservare una zona di memoria dinamicamente si usa l' | ||
+ | ==== memoria automatica ==== | ||
+ | Esempio di variabile gestito automaticamente (facile da usare) | ||
+ | < | ||
+ | |||
+ | ==== New ==== | ||
+ | Se durante la compilazione non si conosce quante variabili saranno necessarie, la memoria si allocherà dinamicamente (invece che automaticamente) con //new//. L' | ||
+ | |||
+ | Esempio: | ||
+ | |||
+ | < | ||
+ | |||
+ | Se la memoria centrale fosse esaurita si otterrebbe da //new// un puntatore null, tuttavia includendo uno specifico header si può ottenere un' | ||
+ | < | ||
+ | |||
+ | |||
+ | Cosa restituisce l' | ||
+ | |||
+ | Dove memorizzare un indirizzo? Quale tipo di dato è utile per memorizzare un indirizzo di memoria? | ||
+ | Anche se un indirizzo di memoria è un numero, non si usa il tipo //int//, ma un tipo di dato speciale chiamato //puntatore a...//. Nel precedente esempio si deve usare un "// | ||
+ | < | ||
+ | float* numero; | ||
+ | numero = new float; | ||
+ | </ | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Nel precedente esempio il programma ha riservato due aree di memoria: | ||
+ | * " | ||
+ | * "new float" come variabile // | ||
+ | Le due operazioni possono essere eseguite anche in un' | ||
+ | {{ : | ||
+ | < | ||
+ | La seconda variabile (nell' | ||
+ | |||
+ | < | ||
+ | |||
+ | Riassumendo, | ||
+ | * inizia la funzione | ||
+ | - definire un puntatore (nella mem. automatica) | ||
+ | - riservare la memoria dinamica con //new// e inizializzare il puntatore | ||
+ | - utilizzare a proprio piacere l'area dinamica... | ||
+ | - liberare la memoria dinamica con //delete// | ||
+ | * termina la funzione (si libera anche il puntatore) | ||
+ | Oppure, in altre parole, ricordarsi di liberare tutte le variabili dinamiche create per evitare problemi di gestione della memoria o falle (memory leak). | ||
+ | I puntatori quindi sono variabili usate prevalentemente per controllare la memoria dinamica (//heap//). | ||
+ | |||
+ | ====Un consiglio==== | ||
+ | Nonostante quanto detto nelle precedenti righe, sarebbe meglio non creare/ | ||
+ | |||
+ | I puntatori (e gli array) lavorano sulla memoria a basso livello, cioè senza quasi nessun controllo, e possono causare oscuri malfunzionamenti e bug! I vector vanno preferiti perché hanno un' | ||
+ | |||
+ | Creando un [[appunti3s: | ||
+ | In ogni caso, non usare direttamente new e delete, ma creare oggetti con new nel costruttore e delete nel distruttore. | ||
+ | |||
+ | ===== Perché usare la memoria dinamica? ===== | ||
+ | |||
+ | La memoria dinamica, rispetto alla memoria automatica, può essere utile per contenere oggetti molto grandi o di dimensioni non note a priori, oppure per contenere oggetti che devono durare a lungo (più della durata degli oggetti locali (automatici) di una funzione). | ||
+ | ===== Perché usare i puntatori? ===== | ||
+ | I puntatori non vengono usati solo per accedere alla memoria heap. | ||
+ | A volte i puntatori permettono di accedere anche a zone della memoria (stack) altrimenti inaccessibili, | ||
+ | A volte i puntatori permettono di puntare alle funzioni, consentendo di eseguire funzioni diverse per condizioni diverse che si possono verificare in tempo di esecuzione (running time), in altre parole i puntatori consentono anche il [[appunti3s: | ||
+ | |||
+ | |||
+ | ===== Differenze tra puntatori e array ===== | ||
+ | < | ||
+ | In linguaggio C scrivere " | ||
+ | |||
+ | La differenza tra una variabile puntatore (int* p) e un indirizzo (& | ||
+ | ===== Similitudini tra puntatori e array ===== | ||
+ | < | ||
+ | Se il puntatore punta all' | ||
+ | < | ||
+ | |||
+ | Nelle dichiarazioni delle funzioni si può usare equivalentemente una qualsiasi delle seguenti due sintassi: rif. standard 13.1-3.3 | ||
+ | < | ||
+ | int fun(int *p);</ | ||
+ | Il passaggio di un array tramite una funzione, avviene sempre tramite un puntatore, ma un array __non__ è un puntatore... | ||
+ | ===== Puntatore appeso ===== | ||
+ | differenza tra | ||
+ | |||
+ | < | ||
+ | return & | ||
+ | // var che si autodistrugge(locale, | ||
+ | < | ||
+ | return puntatore; // restituisce un indirizzo (la copia del contenuto di | ||
+ | // un puntatore) che contiene l' | ||
+ | // un' | ||
+ | |||
+ | ===== Puntatore a void===== | ||
+ | È introdotto nel linguaggio C++ per necessità. | ||
+ | Ovviamente non esistono oggetti //void//. Il tipo //void// viene usato solo per indicare " | ||
+ | |||
+ | Il puntatore //void*// è usato solo per poter puntare qualsiasi cosa, che il programma non sa cosa sia (mentre il programmatore deve sapere cosa e'). | ||
+ | Il tipo //void*// serve solo per copiare un indirizzo di memoria a basso livello e non consente di lavorare sul contenuto della memoria. | ||
+ | |||
+ | Questo significa che per poter lavorare sul contenuto bisogna effettuare un casting verso un altro tipo di puntatore. Mentre il casting tra altri tipi può essere implicito, per i puntatori è necessario usare il casting esplicito... | ||
+ | Mentre esistono conversioni implicite tra float e int, non esiste tra float* e int* | ||
+ | |||
+ | ====== smart pointers ====== | ||
+ | http:// | ||
+ | |||
+ | ====== shared pointers ====== | ||
+ | to do... | ||
+ | |||
+ | > Per ;;tornare all' |