Innholdsfortegnelse:
Video: Big-O notation in 5 minutes — The basics 2025
Hopen er en amorf blokk av minne som ditt C ++-program kan få tilgang til etter behov. Lær om hvorfor det eksisterer og hvordan du bruker det.
Akkurat som det er mulig å sende en peker til en funksjon, er det mulig for en funksjon å returnere en peker. En funksjon som returnerer adressen til en dobbel, er deklarert som følger:
double * fn (void);
Du må imidlertid være veldig forsiktig når du returnerer en peker. For å forstå farene må du vite noe om variabelt omfang.
Begrenset omfang i C ++
Omfanget er det området over hvilket en variabel er definert. Vurder følgende kodestykke:
// Følgende variabel er tilgjengelig for // alle funksjoner og definert så lenge // programmet kjører (globalt omfang) int intGlobal; // Følgende variabel intChild er tilgjengelig // bare til funksjonen og er bare definert // så lenge C ++ utfører barn () eller en // funksjon hvilket barn () samtaler (funksjonsomfang) tomrom (tomrom) {int intChild;} // følgende variabel intParent har funksjon // omfang tom forelder (tomrom) {int intParent = 0; barn(); int intLater = 0; intParent = intLater;} int main (int nArgs, char * pArgs []) {foreldre ();}
Dette programfragmentet begynner med erklæringen av en variabel intGlobal. Denne variabelen eksisterer fra det tidspunktet programmet begynner å kjøre til det avsluttes. Du sier at intGlobal "har programmet omfang. "Du sier også at variabelen" går inn i omfang "selv før funksjonen main () kalles.
Funksjonen main () berører umiddelbart foreldre (). Det første som prosessoren ser i foreldre () er erklæringen av intParent. På dette punktet går intParent i omfang - det vil si intParent er definert og tilgjengelig for resten av funksjonsforelder ().
Den andre setningen i foreldre () er kallet til barnet (). Igjen, oppgir barnet () en lokal variabel, denne gangen intChild. Omfanget av variabelen intChild er begrenset til funksjonsbarnet (). Teknisk sett er intParent ikke definert innenfor barnets omfang () fordi barnet () ikke har tilgang til intParent; Imidlertid fortsetter den variable intParent å eksistere mens barnet () utføres.
Når barnet () utgår, går variabelen intChild utenfor omfanget. Ikke bare er intChild ikke lenger tilgjengelig, det eksisterer ikke lenger. (Minnet som okkupert av intChild, returneres til det generelle bassenget som skal brukes til andre ting.)
Som foreldre () fortsetter å utføre, går den variable intLater inn i omfang ved erklæringen. Når foreldre () returnerer til main (), går både intParent og intLater ut av omfanget.
Fordi intGlobal er erklært globalt i dette eksemplet, er den tilgjengelig for alle tre funksjonene og er fortsatt tilgjengelig for programmets levetid.
Undersøk omfangsproblemet i C ++
Følgende kodesegment kompilerer uten feil, men virker ikke (ikke hater du bare det?):
dobbelt * barn (tomrom) {double dLocalVariable; returnere & dLocalVariable;} ugyldig forelder (tomrom) {double * pdLocal; pdLocal = barn (); * pdLocal = 1. 0;}
Problemet med denne funksjonen er at dLocalVariable er definert bare innenfor funksjonsbarnets omfang (). Dermed er det på den tiden minnesadressen til dLocalVariable returnert fra barnet (), det refererer til en variabel som ikke lenger eksisterer. Minnet som dLocalVariable tidligere okkuperte blir sannsynligvis brukt til noe annet.
Denne feilen er svært vanlig fordi den kan krype opp på flere måter. Dessverre forårsaker denne feilen ikke at programmet umiddelbart stopper. Faktisk kan programmet fungere fint mesteparten av tiden - det vil si at programmet fortsetter å fungere så lenge minnet som tidligere var opptatt av dLocalVariable, ikke gjenbrukes umiddelbart. Slike intermitterende problemer er de vanskeligste å løse.
Gi en løsning ved hjelp av bunken i C ++
Problemproblemet oppstod fordi C ++ tok tilbake det lokalt definerte minnet før programmereren var klar. Det som trengs er en blokk med minne som styres av programmereren. Hun kan allokere minnet og legge det tilbake når hun vil - ikke fordi C ++ synes det er en god ide. En slik blokk av minne kalles bunken.
Heapminne er allokert ved hjelp av det nye søkeordet, etterfulgt av typen objekt å tildele. Den nye kommandoen bryter en bit av minne fra bunken som er stor nok til å holde den angitte typen gjenstand og returnerer adressen sin. For eksempel tildeler følgende en dobbelvariabel utenfor bunten:
dobbelt * barn (tomrom) {double * pdLocalVariable = new double; return pdLocalVariable;}
Denne funksjonen fungerer nå som den skal. Selv om variabelen pdLocalVariable går utenfor omfanget når funksjonsbarnet () returnerer, vil minnet som pdLocalVariable refererer ikke. En minneplass returnert av ny, går ikke ut av omfanget før den eksplisitt returneres til bunken ved hjelp av søkeordet slett, som er spesielt utformet for dette formålet:
tom foreldre (tomrom) {// child () returnerer adressen av en blokk // av haug minne dobbelt * pdMyDouble = barn (); // lagre en verdi der * pdMyDouble = 1. 1; // // // nå tilbake minnet til bunken slette pdMyDouble; pdMyDouble = 0; // …}
Her blir pekeren returnert av barn () brukt til å lagre en dobbel verdi. Etter at funksjonen er ferdig med minnestedet, returneres den til bunken. Funksjonen forelder () setter pekeren til 0 etter at haughukommelsen er returnert - dette er ikke et krav, men det er en veldig god idé.
Hvis programmereren feilaktig forsøker å lagre noe i * pdMyDouble etter slettingen, vil programmet krasje umiddelbart med en meningsfeilmelding.
Du kan bruke ny til å tildele arrays fra bunken også, men du må returnere en matrise ved å slette [] søkeordet:
int * nArray = new int [10]; nArray [0] = 0; slett [] nArray;
Teknisk nytt int [10] påkaller den nye [] operatøren, men det fungerer det samme som nytt.
