PDA

Visualizza la versione completa : [C++] memory leak


mlipreri
08-01-2008, 17:33
Ciao, vorrei sapere se quando creo un oggetto fondamentale nel distruttore fare un delete o qualcosa del genere per rilasciare lo spazio occupato precedentemente in modo da evitare memory leak.
Grazie

MItaly
08-01-2008, 17:39
Se stai parlando di C++ (occhio, il linguaggio va indicato nel titolo), lo spazio occupato in memoria dall'oggetto in s viene liberato automaticamente, nel distruttore devi rilasciare la memoria che hai eventualmente allocato nell'heap con new o malloc e liberare eventualmente altre risorse (ad esempio chiudere file, socket, oggetti del sistema operativo, ...).
Esempio banale:


#include <stdexcept>
//...
class VettoreInt
{
int * interi;
unsigned int numeroInteri;
public:
VettoreInt(unsigned int NumeroInteri)
{
if(NumeroInteri==0)
throw std::invalid_argument("NumeroInteri deve essere maggiore di 0");
numeroInteri = NumeroInteri;
try
{
interi = new int[NumeroInteri];
}
catch(std::bad_alloc & ex)
{
//Spiega un po' meglio al chiamante
throw std::bad_alloc("Impossibile allocare il numero richiesto di interi.");
}
};
~VettoreInt()
{
delete interi[];
};
//... ometto gli altri metodi ...
};

mlipreri
08-01-2008, 17:46
quindi se ho instanziato un oggetto con new devo deallocarlo? se si come?
Grazie ;)

MItaly
08-01-2008, 17:51
Usando delete.


//Primo caso: istanzio la classe sullo stack
void Test1()
{
VettoreInt vi(10);
//...
return;
//Al termine della funzione vi viene automaticamente deallocato
}
//Secondo caso: istanzio la classe nell'heap
void Test2()
{
VettoreInt * vi = new VettoreInt(10);
//...
//vi va deallocato manualmente
delete vi;
return;
}

Tieni comunque conto che questo esempio non ha nulla a che vedere con i distruttori: il codice che impiega la classe che si deve occupare di deallocarne le istanze (come in questo esempio); nel distruttore (che, se l'oggetto allocato nell'heap, viene richiamato solo quando viene distrutto con delete) devi solo eliminare gli oggetti eventualmente allocati sull'heap dalla tua classe.

mlipreri
08-01-2008, 17:52
Ok.
Ma se dentro a un metodo della classe A creo un instanza di un oggetto della classe B alla fine del metodo devo deallocarlo?
Supponendo che l'oggetto classe B sia un oggetto d'appoggio per compiere determinate operazioni istanziato con new e dopo non serve pi.
Grazie

MItaly
08-01-2008, 17:56
Dipende da come lo allochi; se lo allochi sullo stack (come nella funzione Test1) viene deallocato automaticamente al termine della funzione, se lo allochi nell'heap (come nella funzione Test2) lo devi deallocare manualmente con delete.
---EDIT---
Ah, ho letto ora che dici "allocato con new"; allora lo devi deallocare quando non ti serve pi con delete. Ricordati che tutto quello che allochi con new va deallocato con delete.

mlipreri
09-01-2008, 08:03
grazie mille ;)

mlipreri
09-01-2008, 10:05
ad esempio

for ( int i = 0 ; i < list.size() ; i++ )
{
myTestObject * testObject;

testObject = new ( myTestObject , this );

temptwmConfigPool->doSomeThing( );


myObjectList.append ( testObject );

delete testObject;
}
se ometto il delete va tutto bene altrimenti ho un segmentation fault...perch?

oregon
09-01-2008, 10:54
Devi eseguire la delete quando non utilizzi piu' l'oggetto ...

Se lo stai ancora utilizzando, lo presuppongo dal fatto che lo aggiungi ad una collezione con

myObjectList.append ( testObject );

non puoi ancora usare la delete ...

Devi prima eliminarlo dalla collection con un apposito metodo (che so, myObjectList.remove ...)

mlipreri
09-01-2008, 10:59
io pensavo che aggiungendolo alla mia collection potessi eliminarlo...invece no perch ancora in uso :dh:

Loading