knuto Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 Hallo! Eg les, som nokon veit, i ei bok. No har forfattaren begynt å bruke new til meir enn han har forklart. Det er jo greit nok dersom det blir brukt slik: class test { //klasse }//end class test anyname = new test Men forfattaren har begynt å gjere slik: string line; while(getline(inFstream, line)) { textlines.push(new string(line)); }//end while Her er det fleire ting eg ikkje heilt forstår. For det første. line er jo allereie ein string, så kvifor gidde å gjere slik: string(line) på den tredje linja. Det vil jo være heilt unødvendig? Men. Det eg ikkje forstår er. Kvifor ha new string(line). Har eg rett i at det er slik at det blir opretta ein ny plass i minnet der der den nye string(line) ligg? Funksjonen er jo slik: void Stack::push(void* dat) Det vil seie at dat er ein pointer til argumentet (string(line)). Er det difor det blir brukt new til allikevel å lage eit nytt område, i minnet, til argumentet (string(line)), slik at funksjonen ikkje brukar den delen av minnet der den "orginale" line ligg? Phu Vanskeleg å forklare... Lenke til kommentar
☀ ❄ Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 Skjønner godt at dette kan være ganske komplisert å forstå, men jeg skal gjøre mitt beste for å forklare det. (Det ser ut til at du ser svaret selv også. Legg merke til at new lager objekter på heap-en, i motsetning til vanlige, lokale objekter, som blir laget på stack-en.) Som du sier, line er en helt vanlig string. Stack::push() tar en peker som argument, så en helt vanlig string er ikke godt nok. Det han gjør i dette tilfellet er å lage en kopi av stringen på heap-en, vha. new. new returnerer en peker til den nye stringen, og det er akkurat det Stack::push() vil ha. Når new string(line) kalles på den måten blir forresten string sin kopi-konstruktør (copy constructor/cctor) kalt. Jeg vet ikke om du har vært borti kopikonstruktører ennå, men for å gi en rask forklaring i tilfelle du ikke har vært det: Kopikonstruktøren lager en ny string basert på en string den får som argument. Lenke til kommentar
knuto Skrevet 6. februar 2005 Forfatter Del Skrevet 6. februar 2005 Aha. Men... Kva er eigentleg heap-en og stack-en :/ Står ikkje i ordboka... Lenke til kommentar
Dead_Rabbit Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 heap = allokert på "the free store"(altså ikke lokalt, denne må man styre helt og holdent selv). stack = konstuert lokalt, og slettes når objektet går "out of scope". Lenke til kommentar
knuto Skrevet 6. februar 2005 Forfatter Del Skrevet 6. februar 2005 Vil det seie at dersom du lager objekt på heap'en og ikkje delete'ar han, vil denne oppta plass i minnet til programmet sluttar å køyre? Eller til maskinen blir avslutta? Lenke til kommentar
Dead_Rabbit Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 Hvis du ikke deleter den så vil du få en minnelekasje(det blir båndlagt og du kan ikke bruke det igjen). Programmet deleter den ikke for deg når programmet avsluttes. Lenke til kommentar
A_N_K Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 Mener at OS typisk frigjør alt minne et program har allokert når programmet terminerer? Problemet er vel ukontrollert minneforbruk under kjøring. Lenke til kommentar
Dead_Rabbit Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 Sikker? Jeg er ganske sikker på at man "mister" det for godt.. Lenke til kommentar
A_N_K Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 Jeg ser ingen grunn til at OS'et ikke skal frigjøre allokert minne ved programmets avslutning? Lenke til kommentar
kjetil7 Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 Det er avhengig av hvilket OS du kjører. De fleste moderne OS som de fleste av oss bruker i dag vil minne bli frigjort ved programmets avslutning. Men noen OS, som f.eks. gamle Windows 3.1 må du boote før du får frigjort minne. Lenke til kommentar
A_N_K Skrevet 6. februar 2005 Del Skrevet 6. februar 2005 (endret) Stemmer bra med min oppfatning :7 Det var forsåvidt ikke verre enn å skrive et enkelt C-program, som allokerte en passende mengde minne. Endret 6. februar 2005 av A_N_K Lenke til kommentar
CronoMan Skrevet 7. februar 2005 Del Skrevet 7. februar 2005 Det er avhengig av hvilket OS du kjører. De fleste moderne OS som de fleste av oss bruker i dag vil minne bli frigjort ved programmets avslutning. Men noen OS, som f.eks. gamle Windows 3.1 må du boote før du får frigjort minne. Men noen OS, som f.eks. gamle Windows 3.1 må du boote før du får frigjort minne. Win 3.1 er ikke et OS Windows 9x firgjør heller ikke minne uten videre, fordi den mangler garbage collector. Windows NT platformer frigjør alt minnet et program har allokert når programmet blir lukket. Uansett om du bruker new eller malloc. Nå vet ikke jeg veldig my om stack og slikt, men etter som jeg har forstått er det bare temporære variabler som blir lagt i stack; int a, char a, etc. Hvis man tar malloc (eller new) så blir variablen allokert i det virkelige minnet som programmet har tilgjengelig. Lenke til kommentar
Steinbitglis Skrevet 7. februar 2005 Del Skrevet 7. februar 2005 Mener å ha hørt et sted at win 95 selv har en minnelekasje. Altså kan ikke maskina stå på i all evighet fordi minnet fylles opp. Lenke til kommentar
knuto Skrevet 7. februar 2005 Forfatter Del Skrevet 7. februar 2005 Men... Kva er vitsen med å bruke heap'en når du liksågodt kan bruke stack'en? Fartsforskjellar? Lenke til kommentar
saboi Skrevet 7. februar 2005 Del Skrevet 7. februar 2005 stacken er mye raskere enn heapen, men den er mye mindre Lenke til kommentar
A_N_K Skrevet 7. februar 2005 Del Skrevet 7. februar 2005 (endret) Men... Kva er vitsen med å bruke heap'en når du liksågodt kan bruke stack'en? Kan du det? Stack-objekter poppes altså automatisk når de går ut av skop, mens objekter på heap'en eksisterer uavhengig av stack-kontekst til de slettes (eller programmet terminerer). Hvis du skal dele attributter (dvs. de refererer alle til samme objekt) mellom objekter f.eks må enten ett av disse objektene eie selve attributt-objektet og dele ut referanser, noe som fort kan bli komplisert, eller så kan deling foregå vha. pekere til et heap-objekt. Med smart automatisert minnedeallokering kan sistnevnte gjennomføres uten særlig hodebry. Endret 7. februar 2005 av A_N_K Lenke til kommentar
Feynman Skrevet 7. februar 2005 Del Skrevet 7. februar 2005 Men... Kva er vitsen med å bruke heap'en når du liksågodt kan bruke stack'en? Fartsforskjellar? En stack brukes av en funksjon i programmet ditt, mens heapen brukes av selve programmet. Heapen er nyttig hvis du skal dele data mellom flere prosesser eller objekter, eller flere funksjoner (et alternativ til globale variabler). Lenke til kommentar
kjetil7 Skrevet 8. februar 2005 Del Skrevet 8. februar 2005 (endret) Men... Kva er vitsen med å bruke heap'en når du liksågodt kan bruke stack'en? Fartsforskjellar? Stacken bruker en såkalt LIFO anordning ("last in first out") for å allokere plass i minnet. Dvs. at den siste allokerte variablen *må* være den første som deallokeres. Allokering og deallokering på stacken innebærer egentlig bare å flytte stackpekeren fram og tilbake et visst antall bytes. Dette er veldig raskt i forhold til å allokere på heapen som er organisert i mer kompliserte segmenter og som du kan allokere og deallokere stort sett som du vil i. Som du kanskje har forstått er det lite hensiktsmessig og alltid deallokere i motsatt rekkefølge som du allokerer. Hvis du kun skulle brukt en stack måtte du tatt vare på masse "søppel" som f.eks. temporære variabler og ikke minst funksjonsparametre og instruksjosnspekere (peker til neste instruksjon som skal kjøres av prosessoren, eng. instruction pointer, som forkortes IR) som også lagres på stacken. Det er også verdt å nevne at stackpekeren er lagret i SP-registret (SP = stack pointer) i prosessoren og den har derfor veldig rask tilgang til stacken. Kunne skrevet mye mer om stack vs. heap, men jeg håper det meste er dekket nå . Windows 9x firgjør heller ikke minne uten videre, fordi den mangler garbage collector. Ganske sikker på at du tar feil her. Men jeg skal ikke avvise det helt før jeg har sjekket det nærmere. Garbage collector er et begrep jeg først og fremst forbinder med implentasjoner av programmeringsspråk. Endret 8. februar 2005 av kjetil7 Lenke til kommentar
JBlack Skrevet 9. februar 2005 Del Skrevet 9. februar 2005 (endret) Ikke rart folk blir forvirra... heap'en: et område av minnet som kan brukes av programmer til generell lagring av data. stack'en: et område av minnet som brukes til lagring data som har med programmets flyt å gjøre. Denne brukes vanligvis ikke direkte i program, men brukes indirekte, for eksempel når man kaller funksjoner. Når man kaller en funksjon så lagres returadressen på stack'en. Når man returnerer fra en funksjon så hentes returadressen. En stack: En datastruktur med egenskapen først inn, sist ut. Eller sist inn, først ut, som blir det samme. Man har altså generelt ikke tilgang til annen data enn det siste som er lagret på stack'en. Skal man ha tak i tidligere data så må man først fjerne det som er lagt inn senere. Og da er det borte for godt. Denne typen datastruktur er godt egnet for å kontrollere flyt av programmer. stack'en har derfor denne datatypen. For å legge noe på toppen av stack'en bruker man kommandoen push. For å ta vekk det som ligger på toppen, bruker man pull. Man kan ofte manipulere en stack utover det som er beskrevet ovenfor, men det er ikke vanlig. Og har man behov for å gjøre det, så har man valgt feil datatype. I programutsnittet ditt så brukes en stack, ikke stack'en til selve programmet. Det er altså lagetat en datastruktur av typen stack. Men stack'en som kontrollerer flyten til programmet, den blir ikke manipulert her. I c++ er det forskjell på objekter og pekere til objekter. En variabel kan være enten eller. C++ holder orden på dette for deg (det er derfor man må bruke casting når man blander forskjellige typer). Det som skjer i programutsnittet er at du har et objekt av typen string. Denne stringen finnes et sted i minnet (heap'en). Programmet ønsker å lagre denne i en stack. Men stack'en kan ikke lagre avanserte datatyper, bare pekere. Derfor brukes new(...) til å lage et nytt objekt i minnet (nå finnes to identiske string objeketer i heap'en) og returnerer en peker til denne. Det er så denne pekeren som lagres (pushes) i en stack. Objekter vil opphøre og eksistere, og dets minne vil bli frigjort, ved enedn av objektets 'scope'. Som regel innenfor de { } der det er laget. Men ting som allokeres i minnet ved hjelp av new vil ikke blir frigjort. Eksempel: void f(void){ int *a = new int(3); int b=3; } Denne koden vil opprette en peker til en integer (a) og en integer (b). På slutten av funksjonen vil minnet brukt til pekeren a og integeren b frigjøres. MEN! Minnet som a peker på bil ikke firgjøres! Et eller annet sted i heap'en svever nå et tre-tall, og ingen vet lenger hvor. Dette utgjør en minnelekkasje. For hver gang funksjonen kalles vil man miste size(int) minne. På 32 bits systemer 4 byte. Edit: Det er ingen garanti for at alt minne et objekt bruker skal bli frigjort. Det som skjer når et objekt ender sin levetid er at destruktoren kalles. Destruktorens ansvar er da å frigjøre (delete) det minnet objektet eventuelt har allokert (new). Endret 9. februar 2005 av JBlack Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå