Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: [c++] Muistin vapautus

connor [28.07.2009 20:52:46]

#

Eli olen aivan aivan ja vielä kerran aivan aloittelija c++ ohjelmoinnissa. Luin jostain että c++ ei vapauta itsestään muistia. Eli jos luon muuttuja x:n niin pitääkö minun jotenkin ihmeessä vapauttaa tuo muuttuja x?

Jos tarvii jotain tietoa niin käytän visual studio 2008 standardia.

Grez [28.07.2009 21:15:51]

#

Kyllä C++ vapauttaa automaattisesti kaiken muistin, jonka se varaa automaattisesti (esim. muuttujat). Jos taas varaat muistia itse (new -komento) niin se täytyy myös vapauttaa itse (delete -komento)

groovyb [28.07.2009 22:03:22]

#

jos käytät c++/cli:tä,niin garbage collection tuhoaa sen automaagisesti jos käytät gcnew:iä.

Joku^ Jotain = gcnew Joku();

koo [28.07.2009 23:39:59]

#

Aivan aloittelija ei yleensä ole missään tekemisissä C++/CLI:n kanssa, joten siitä puhuminen taitaa vain sotkea asioita.

Kuten Grez sanoi, tavanomaisten muuttujien muistinhallinta hoituu C++:ssa automaattisesti. Esimerkki:

struct luokka { int i; };

int main()
{
  luokka m;
  m.i = 1;
}

Tuo "ei vapauta itsestään muistia" liittyy C++:ssa dynaamiseen muistinhallintaan, josta on hiljattain ollut juttua. Siinä muisti täytyy varata ja vapauttaa erityisillä new- ja delete-lausekkeilla:

struct luokka { int i; };

int main()
{
  luokka *p = new luokka;
  p->i = 2;
  delete p;
}

Tuossa p on osoitinmuuttuja, joka kyllä itsessään luodaan ja tuhotaan automaattisesti, mutta se varsinainen olio, johon osoitin osoittaa, täytyy luoda ja tuhota newillä ja deletellä.

Joissakin kielissä dynaamiseen muistinhallintaan liittyy roskankeruu, jolloin deleteä ei tarvita, mutta näin ei ole C++:ssa. Molemmilla tavoilla on kannattajansa uskonnolliseen fanatismiin saakka, vaikkei kumpikaan ole ehdottoman ainoa oikea kaikissa tilanteissa.

C++:ssan standardikirjastosta löytyy kuitenkin apukeinoja siihen, että myös dynaamisen muistin hallinta voitaisiin tehdä mahdollisimman automaattisesti:

#include <memory>

struct luokka { int i; };

int main()
{
  std::auto_ptr<luokka> ap(new luokka);
  ap->i = 3;
}

Tuossa ap on fiksu osoitinmuuttuja (smart pointer), joka luodaan ja tuhotaan automaattisesti. Olio, johon se osoittaa, täytyy kyllä luoda newillä, mutta tuhoaminen tapahtuu automaattisesti, kun osoitinmuuttuja tuhoutuu.

Yleensä paljaiden osoitinmuuttujien käyttöä kannattaa vältellä ja käyttää niiden sijasta erilaisia fiksumpia osoittimia sekä kokoelmaluokkia (container).

Grez [28.07.2009 23:52:30]

#

No jos kerran Visual Studio 2008:a käyttää niin ei toi CLI niin hirmu kaukaa haettu vaihtoehto ole. Sanoisin että jos vaikkapa konsoliapplikaatiota olisi tekemässä niin aloittajalla on melkinpä tuurista kiinni sattuuko valitsemaan "win32 console application" vai "clr console application"

Pekka Karjalainen [30.07.2009 13:31:40]

#

koo kirjoitti:

Joissakin kielissä dynaamiseen muistinhallintaan liittyy roskankeruu, jolloin deleteä ei tarvita, mutta näin ei ole C++:ssa. Molemmilla tavoilla on kannattajansa uskonnolliseen fanatismiin saakka, vaikkei kumpikaan ole ehdottoman ainoa oikea kaikissa tilanteissa.

Itse asiassa Boehmin roskienkeruukirjasto antaa sangen toimivan ratkaisun tähän C- ja C++-kieliin. Sitä voi käyttää myös ohjelman muistivuotojen testaukseen, missä tapauksessa sen tietenkin sitten jättää pois ohjelman julkaisuversiosta.

Se on kyllä totta, että roskienkeruuta koskevat keskustelut harvemmin keskittyvät vain tekniikan etujen ja haittojen rauhalliseen arviointiin, vaan siirtyvät sen sijaan arvioimaan keskusteluun osallistujien ohjelmointitaitoa, älynlahjoja tai sukupuun rakennetta. Ilmeisesti tähänkin on syynä se, että asian kunnollinen arvioiminen vaatii niin syvällistä osaamista, että sitä ei vain useimmilta löydy. (Tämä siis tapahtuu joskus joissakin muissa foorumeissa, eikä meidän sivistyneessä Putkassamme.)

Aloittelijan on toki viisas oppia kielen käyttö ensin standarditavalla ja sitten vasta tutkia edistyneempiä tekniikoita.

Roskienkeruussa on sekin puoli, että sitä tehokkaimmin käyttävät ohjelmat kannattaa toisinaan kirjoittaa eri tavalla kuin tuttuja menetelmiä käyttävät. Monesti tekniikoiden "nopeutta" vertailevat unohtavat tämän, ja tulevat sitten tulokseen, että se oma suosikkitapa on aina nopeampi ja parempi. Osalle keskustelijoista taas tutkimuksen teko aiheesta vaikuttaa tarpeettomalta, kun oikean mielipiteen sai jo syntyessä :). Jätetään kuitenkin nämä flamet pois Putkasta, jooko? Jos joku lukee minun yllyttävän käyttämään jotakin menetelmää, pois se virheluulo. Suositan omaa harkintaa ja perustekniikoiden hallintaa ennen kaikkea.

URLista lisää tietoa halukkaille:

http://www.hpl.hp.com/personal/Hans_Boehm/gc/
http://www.hpl.hp.com/personal/Hans_Boehm/gc/leak.html

groovyb [31.07.2009 00:38:17]

#

Lähinnä tarkoitinkin että jos käytössä on visual studio 2008, ja on aloittanut visual c++ harjoittelemaan, niin ei tuo gcnew ole mikään erikoinen asia.

aloittaja ei myöskään välttämättä erota käyttääkö cli:tä vai ei, ehkä ainoastaan * tilalla oleva ^ ja gcxxx:t ovat visuaalisia eroja aloittelijalle.

myöskin se, että käytössä on vs standard eikä express, vihjaa minulle siitä että kokemusta muista kielistä on, koska käytössä on kaupallinen editori.

tunnen useita jotka ovat aloittaneet ohjelmoinnin visual studion ja .netin kautta, ja heille automaattinen roskankeruu ei ole mikään "uusi" juttu, saatika, että ovat siirtyneet vb.netistä tai C#:sta c++:aan, juurikin tuolle c++/cli puolelle suoraan, eivät perinteisen c++:n kautta.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta