Casa Finanza personale Come funziona l'heap in C ++ - dummies

Come funziona l'heap in C ++ - dummies

Sommario:

Video: Método Heap Sort , Algoritmo de Ordenamiento, Programación Avanzada 2024

Video: Método Heap Sort , Algoritmo de Ordenamiento, Programación Avanzada 2024
Anonim

L'heap è un blocco di memoria amorfo a cui il programma C ++ può accedere se necessario. Scopri perché esiste e come usarlo.

Così come è possibile passare un puntatore a una funzione, è possibile che una funzione restituisca un puntatore. Una funzione che restituisce l'indirizzo di una doppia viene dichiarata come segue:

double * fn (void);

Tuttavia, si deve fare molta attenzione quando si restituisce un puntatore. Per capire i pericoli, devi sapere qualcosa sull'ambito della variabile.

Ambito limitato in C ++

L'ambito è l'intervallo su cui è definita una variabile. Si consideri il seguente frammento di codice:

// la seguente variabile è accessibile a // tutte le funzioni e definita fintanto che // programma è in esecuzione (ambito globale) int intGlobal; // la seguente variabile intChild è accessibile // solo alla funzione ed è definita solo // fintanto che C ++ sta eseguendo child () o una funzione // quale child () chiama (scope della funzione) void child (void) {int intChild;} // la seguente variabile intParent ha la funzione // scope void parent (void) {int intParent = 0; bambino(); int intLater = 0; intParent = intLater;} int main (int nArgs, char * pArgs []) {parent ();}

Questo frammento di programma inizia con la dichiarazione di una variabile intGlobal. Questa variabile esiste dal momento in cui il programma inizia l'esecuzione fino alla sua conclusione. Si dice che intGlobal "ha portata del programma. "Si dice anche che la variabile" entra nell'ambito "anche prima che venga chiamata la funzione main ().

La funzione main () richiama immediatamente parent (). La prima cosa che il processore vede in parent () è la dichiarazione di intParent. A quel punto, intParent entra nel campo di applicazione, ovvero intParent è definito e disponibile per il resto della funzione parent ().

La seconda istruzione in parent () è la chiamata a child (). Ancora una volta, la funzione child () dichiara una variabile locale, questa volta intChild. L'ambito della variabile intChild è limitato alla funzione child (). Tecnicamente, intParent non è definito nell'ambito di child () perché child () non ha accesso a intParent; tuttavia, la variabile intParent continua ad esistere mentre child () è in esecuzione.

Quando termina child (), la variabile intChild esce dallo scope. IntChild non solo non è più accessibile, non esiste più. (La memoria occupata da intChild viene restituita al pool generale per essere utilizzata per altre cose.)

Mentre genitore () continua ad essere eseguito, la variabile intLater entra nell'ambito della dichiarazione. Al punto che parent () torna a main (), sia intParent che intLater escono dall'ambito.

Poiché intGlobal è dichiarato globalmente in questo esempio, è disponibile per tutte e tre le funzioni e rimane disponibile per la vita del programma.

Esaminare il problema dell'ambito in C ++

Il seguente segmento di codice compila senza errori ma non funziona (non lo odi?):

double * child (void) {double dLocalVariable; return & dLocalVariable;} void parent (void) {double * pdLocal; pdLocal = child (); * pdLocal = 1. 0;}

Il problema con questa funzione è che dLocalVariable è definita solo nell'ambito della funzione child (). Quindi, quando l'indirizzo di memoria di dLocalVariable viene restituito da child (), fa riferimento a una variabile che non esiste più. La memoria che dLocalVariable precedentemente occupata è probabilmente utilizzata per qualcos'altro.

Questo errore è molto comune perché può insinuarsi in vari modi. Sfortunatamente, questo errore non causa l'arresto istantaneo del programma. In effetti, il programma può funzionare bene la maggior parte del tempo - cioè, il programma continua a funzionare finché la memoria precedentemente occupata da dLocalVariable non viene riutilizzata immediatamente. Tali problemi intermittenti sono i più difficili da risolvere.

Fornire una soluzione utilizzando l'heap in C ++

Il problema dell'ambito è stato generato poiché C ++ ha recuperato la memoria definita localmente prima che il programmatore fosse pronto. Ciò che è necessario è un blocco di memoria controllato dal programmatore. Può allocare il ricordo e rimetterlo quando vuole - non perché C ++ pensa che sia una buona idea. Un tale blocco di memoria è chiamato heap.

La memoria heap viene allocata utilizzando la nuova parola chiave seguita dal tipo di oggetto da allocare. Il nuovo comando rompe un mucchio di memoria dall'heap abbastanza grande da contenere il tipo specificato di oggetto e restituisce il suo indirizzo. Ad esempio, il seguente alloca una doppia variabile dall'heap:

double * child (void) {double * pdLocalVariable = new double; return pdLocalVariable;}

Questa funzione ora funziona correttamente. Sebbene la variabile pdLocalVariable vada fuori campo quando la funzione child () restituisce, la memoria a cui fa riferimento pdLocalVariable non lo fa. Una posizione di memoria restituita da new non esce dall'ambito finché non viene esplicitamente restituita all'heap utilizzando la parola chiave delete, che è specificatamente progettata per tale scopo:

void parent (void) {// child () restituisce l'indirizzo di un blocco // di memoria heap double * pdMyDouble = child (); // memorizza un valore lì * pdMyDouble = 1. 1; // … // ora restituisce la memoria allo heap delete pdMyDouble; pdMyDouble = 0; // …}

Qui il puntatore restituito da child () viene utilizzato per memorizzare un valore double. Al termine della funzione con la posizione di memoria, viene restituito all'heap. La funzione parent () imposta il puntatore su 0 dopo che è stata restituita la memoria dell'heap - questo non è un requisito, ma è un'ottima idea.

Se il programmatore tenta erroneamente di memorizzare qualcosa in * pdMyDouble dopo l'eliminazione, il programma si bloccherà immediatamente con un messaggio di errore significativo.

Puoi usare new per allocare array anche dall'heap, ma devi restituire un array usando la parola chiave delete []:

int * nArray = new int [10]; nArray [0] = 0; delete [] nArray;

Technically new int [10] richiama il nuovo [] operatore ma funziona come nuovo.

Come funziona l'heap in C ++ - dummies

Scelta dell'editore

Come utilizzare le funzionalità dell'app Klout su dispositivi Apple - dummies

Come utilizzare le funzionalità dell'app Klout su dispositivi Apple - dummies

L'esperienza mobile di Klout è più limitato rispetto al sito web completo. Tuttavia, molte funzionalità sono ancora disponibili con l'app per dispositivi mobili, incluso dare + K ai tuoi influenzatori, controllare il tuo punteggio Klout e apportare semplici modifiche al tuo profilo. E con l'implementazione di Klout per il tuo iPhone Passbook puoi persino usare Klout per ottenere ...

Metriche dei social media: App Android SDK di Google Analytics - dummies

Metriche dei social media: App Android SDK di Google Analytics - dummies

Tracciamento delle metriche di un'applicazione ( un'app) è stata semplificata, ma le app sono ancora isolate. Puoi tenere traccia di ogni app, ma le soluzioni sono ancora in fase di creazione per tenere traccia di tutte le app. Per andare avanti con Google Analytics SDK per la tua app Android, segui questi passaggi: Scarica l'SDK di Google Analytics per Android. Aggiungi la libreria libGoogleanalytics. jar ...

Metriche sui social media: individuazione del momento di trazione con Google+ - dummies

Metriche sui social media: individuazione del momento di trazione con Google+ - dummies

In i social media, il momento di trazione potrebbe anche essere chiamato il "miglior tempo per condividere su Google+ o altri siti sociali. "Il momento migliore per te potrebbe non essere il momento migliore per i tuoi colleghi generatori di contenuti. (Il merito di questo suggerimento principale va a Christopher Penn che per primo condivise la sua osservazione sulla ricerca ...

Scelta dell'editore

Combinazione di due foto sulla tua Nikon D3400 con sovrapposizione immagini - manichini

Combinazione di due foto sulla tua Nikon D3400 con sovrapposizione immagini - manichini

L'opzione Sovrapposizione immagini sulla Il menu di ritocco di Nikon D3400 consente di unire due foto in una. Questa opzione è stata utilizzata per combinare una foto di un lupo mannaro, mostrato a sinistra, con una scena da giardino notturno, mostrata nel mezzo. Il risultato è l'immagine spettrale mostrata a destra. Oooh, spaventoso! Su ...

Scelta di una modalità Esposizione per una Nikon DSLR - manichini

Scelta di una modalità Esposizione per una Nikon DSLR - manichini

La prima impostazione da prendere in considerazione quando si le riprese con la tua Nikon D3100, D5100 o D7000 sono la modalità di esposizione, che puoi selezionare tramite la ghiera dei modi. La tua scelta determina la quantità di controllo che hai rispetto a due impostazioni di esposizione critiche - diaframma e tempo di posa - oltre a molte altre opzioni, incluse quelle relative ...

Scelta del formato immagine JPEG per una reflex Nikon - dummies

Scelta del formato immagine JPEG per una reflex Nikon - dummies

Offerte Nikon D3100, D5100 o D7000 i due tipi di file comuni nella maggior parte delle fotocamere digitali odierne: JPEG e Camera Raw, o semplicemente Raw in breve, che passa dallo specifico moniker NEF (Nikon Electronic Format) sulle fotocamere Nikon. Il tipo di file, talvolta noto anche come formato file, determina come i dati dell'immagine ...

Scelta dell'editore

Comprensione della struttura delle classi Java - dummies

Comprensione della struttura delle classi Java - dummies

Impossibile creare un'applicazione Java senza creare una classe. Tuttavia, i modi in cui si usano le classi all'inizio quando si apprendono su di essi sono stati relativamente semplicistici - Java è in grado di avere una complessità considerevolmente maggiore, che è il punto di questo capitolo. Le classi hanno una struttura specifica. Proprio come i progetti ...

Come utilizzare i metodi astratti in Java - dummies

Come utilizzare i metodi astratti in Java - dummies

Sia le interfacce che le classi astratte hanno metodi astratti in Java. Ma i metodi astratti giocano ruoli leggermente diversi in questi due tipi di tipi di riferimento. Come puoi tenere tutto dritto nella tua mente? La prima cosa da fare è ricordare che nessuno impara a conoscere i concetti di programmazione orientata agli oggetti senza ottenere molti ...

Come utilizzare l'interfaccia CharSequence in Java - dummies

Come utilizzare l'interfaccia CharSequence in Java - dummies

L'API Java include un'interfaccia utile chiamata CharSequence. Tutte e tre queste classi - String, StringBuilder e StringBuffer - implementano questa interfaccia. Questo metodo esiste principalmente per consentire di utilizzare String, StringBuilder e StringBuffer in modo intercambiabile. A tal fine, molti dei metodi delle classi String, StringBuilder e StringBuffer utilizzano CharSequence come parametro ...