Gå til innhold

Bruk av delete på pekere


Anbefalte innlegg

Hei!

Jeg er ny i c++, men har endel kunnskap fra Java og andre språk.

 

Jeg leste i en tutorial at man må bruke delete på pekere for å unngå memoryleaks.

Eks:

Foo* myFoo = new Foo();
delete myFoo;

 

Men gjelder dette også når pekeren peker til en instanse?

eks:

Foo myFoo;
Foo *myFooPtr = &myFoo;

delete myFooPtr;

 

Må man slette myFooPtr, eller tar GC seg av dette selv da det finnes en instans av objektet?

 

Takker for svar!

Lenke til kommentar
Videoannonse
Annonse
Hei!

Jeg er ny i c++, men har endel kunnskap fra Java og andre språk.

 

Jeg leste i en tutorial at man må bruke delete på pekere for å unngå memoryleaks.

Eks:

Foo* myFoo = new Foo();
delete myFoo;

 

Men gjelder dette også når pekeren peker til en instanse?

eks:

Foo myFoo;
Foo *myFooPtr = &myFoo;

delete myFooPtr;

 

Må man slette myFooPtr, eller tar GC seg av dette selv da det finnes en instans av objektet?

 

Takker for svar!

7666420[/snapback]

 

C++ har ingen GC. Variables som deklareres på stacken, som myFoo i ditt siste eksempel, blir ryddet opp når scopet de er deklarert i avsluttes.

 

Eksempel:

{
 Foo f;
}
// f er nå deallokert, siden scopet ble avsluttet

 

For å svare på spørsmålet ditt: man skal ikke slette pekere som man ikke har allokert i utgangspunktet, med mindre annet spesifiseres av API'et som ble brukt til å fremskaffe pekeren. I ditt siste eksempel skal altså delete *ikke* brukes. Noe annet vil i verste fall føre til et såkalt "double free", som potensielt gjør programmet ditt sårbart for heap overflows.

Lenke til kommentar

Ok, takk for svar!

 

Jeg har sett litt på C før C++ og har et par spørsmål til rundt det.

 

1. Brukes malloc/alloc i C++, eller kun new?

 

2. Bruker dere char[] for strenger eller string klassen som jeg såvidt har vært borti?

Lenke til kommentar
Ok, takk for svar!

 

Jeg har sett litt på C før C++ og har et par spørsmål til rundt det.

 

1. Brukes malloc/alloc i C++, eller kun new?

 

2. Bruker dere char[] for strenger eller string klassen som jeg såvidt har vært borti?

7666860[/snapback]

 

malloc/alloc i C, new/new[]/delete/delete[] i C++.

 

Utover det bør du holde deg til klassene STL tilbyr, som string, vector, list og deque. I stedet for å bruke new osv. direkte, bør du holde deg til C++'s auto_ptr og pointerklassene fra boost (www.boost.org).

Lenke til kommentar

Hvis det hjelper er det en tommerfingerregel som sier at du alltid skal bruke delete på objekter du bruker new på. Ellers skal du ikke bruke delete.

 

Det meste sagt allerede, men jeg kaster meg på anbefalingene om bruk av auto_ptr og standardbiblioteket. De er laget for å hjelpe deg. De kan dessuten brukes til å gjøre koden mer lesbar. Eks:

 

class foo
{
public:
   
   void take_ownership(std::auto_ptr<std::string> str);
   
   std::auto_ptr<std::string> release_ownership();
};

 

Ved å bruke auto_ptr på denne måten vil det ikke være tvil om at den første metoden tar eierskap og den andre gir fra seg eierskap selv uten noe dokumentasjon. Hvis du kun sendte inn en peker ville brukeren av koden vært avhengig av å lese dokumentasjonen og/eller kildekoden for å være helt sikker på hva som skjer med objektet. I mine C++ prosjekter bruker jeg alltid auto_ptr på denne måten. Unntaket er når du er avhengig av "covariant return types" som f.eks. polymorfiske copy-c'tors (Clone). Da må det dokumenteres! :)

Lenke til kommentar

La oss si:

 

int *minpeker;

 

Dette er jo en peker som vi ikke har initialisert. Denne peker jo ikke til noe, og derfor så trenger vi ikke delete den heller.

 

MyObject *peker = new MyObject();

 

Her har jeg opprettet et objekt, på samme måte som i C# og Java, og får peker til å peke på den.

 

I java så kan man da sette peker til null f.eks for å kvitte seg med objektet.

 

peker = null;

 

Gjør du dette når den egentlig peker til MyObject så vil MyObject ligge i minnet fortsatt, men vi har mistet hvor det ligger. For en peker inneholder kun minneadressen til hvor objektet befinner seg. Dette kalles minnelekasje.

 

Derfor:

delete peker;

peker = null;

 

Trenger ikke sette peker = null, men greit hvis du tester senere. if( peker == null ) { peker = new MyObject; }.

 

Så har man brukt new, skal man bruke delete. men delete kan ikke brukes når man ikke har brukt new.

I java så gir man jo blanke (digg oftest), men c++ er litt gammeldags der. Dette går greit som oftest bare man er strukturert, men er du en spagettikoder .... godd luck sier jeg da :)

Lenke til kommentar

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...