Newsgroup: it.comp.lang.c++
Titolo: memoria STL list

Salve
Qualcosa mi sfugge nel funzionamento di una list
come si fa a liberare la memoria che la lista si č allocata??
Esempio:
class MiaClasse
{
     private:
          std::list<int> listaInteri;
     public:
          void metodo1();
          ~MiaClasse();
};
void MiaClasse::metodo1()
{
   for(int i = 0; i<1000000; i++)
   {
      this->listaInteri.push_back(10);
   }
}
MiaClasse::~MiaClasse()
{
   this->listaInteri.clear();
}
Se poi scrivo:
 MiaClasse *a = new MiaClasse();
  a->metodo1();
  delete a;
anche quando distruggo l'oggetto, la memoria resta allocata  :-?
c'entrano qualcosa gli allocator?
Grazie.

 c'entrano qualcosa gli allocator?
non proprio... non per quello che stai chiedendo.
Tommaso
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 no.
Purtroppo il codice che ho postato l'ho compilato e provato, e non libera la
memoria. Utilizzo il Borland c++ 6 e quando distruggo l'oggetto la memoria
resta allocata.
La libera solo quando il programma termina.

 è proprio questo il problema .... non la libera!
spiegami come hai dimostrato a te stesso che non libera la memoria...



Debug passo passo del programma + task manager di windows per vedere
l'andamento della memoria utilizzata.

 Debug passo passo del programma 
se segui il flow del programma fino all'implementazione di list vedrai
che la memoria viene deallocata.
Ad esempio in vc++2005 ~list() chiama _Tidy()
_Tidy() tra le altre cose chiama clear() (che tu chiamavi
esplicitamente)
e clear() tra le altre cose ha questo ciclo:
for (; _Pnode != _Myhead; _Pnode = _Pnext)
{	// delete an element
  _Pnext = _Nextnode(_Pnode);
  this->_Alnod.destroy(_Pnode);
  this->_Alnod.deallocate(_Pnode, 1);
}
che come si intuisce, per ogni nodo della lista, distrugge l'oggetto e
libera la memoria.
Difficile credere che il borland non liberi la memoria...
Prova a debuggare meglio!



Rifatta la prova ma continua a non liberarla!
e all'interno della clear c'è :
template <class _Tp, class _Alloc>
void
_List_base<_Tp,_Alloc>::clear()
{
  _List_node<_Tp>* __cur = (_List_node<_Tp>*)
this->_M_node._M_data->_M_next;
  while (__cur != this->_M_node._M_data) {
    _List_node<_Tp>* __tmp = __cur;
    __cur = (_List_node<_Tp>*) __cur->_M_next;
    _Destroy(&__tmp->_M_data);
    this->_M_node.deallocate(__tmp, 1);
  }
  this->_M_node._M_data->_M_next = this->_M_node._M_data;
  this->_M_node._M_data->_M_prev = this->_M_node._M_data;
}
anche qui fa il destroy e deallocate, ma continua a non funzionare!

 task manager di windows[...]
Non è significativo quanto riportato dal Task Manager di Windows, se
il fine è quello di determinare se la memoria viene liberata o meno.


Perchè no? l'ho sempre utilizzato e ha sempre funzionato, non sarà il
massimo della precisione,
ma se allochi una discreta quantità di mem e poi la liberi, dal task manager
lo vedi.

 l'andamento della memoria utilizzata.
Nel Task Manager, in View->Select Columns, seleziona "Virtual Memory 
Size" e fai riferimento a "VM Size".
Kiuhnm

 massimo della precisione,
Che intendi per "funzionato" ? ... Il sistema operativo, nonché l'Heap
Manager del tuo sistema, adotta la tecnica che più lo aggrada, nella
gestione dei blocchi allocati (ad esempio, non è detto che successive
allocazioni ricorrano sempre alla VirtualAlloc() di Windows: lo Heap
Manager potrebbe preallocare certe quantità di memoria e semplicemente
renderle libere o meno con le deallocazioni/allocazioni).  Lo so
benissimo che se allochi una certa quantità di memoria e la deallochi,
dal TM *puoi* vedere che la memoria torna libera, ma sta di fatto che
questa tecnica non è sufficiente a capire che il sistema abbia
rilasciato o meno la memoria.

 rilasciato o meno la memoria.
ok hai ragione infatti facendo questa prova
for(int i= 0;i<200;i++)
{
      a = new MiaClasse();
      a->metodo1();
      delete a;
}
la memoria nel TM  sale solo durante il primi ciclo, per i seguenti 199
resta identica!
Insomma ho sempre avuto un gran culo ad usare il TM ??????
Quindi la nuova domanda è : tu cosa usi per capire se la mem  viene
allocata/deallocata???

 anche qui fa il destroy e deallocate, ma continua a non funzionare!
Cosa vuole dire che continua a non funzionare?
Se ci sono quelle due righe e le esegue (o quando chiami clear
direttamente o tramite il distruttore) allora vuole dire che libera la
memoria.
Come fai a dire che non funziona? Dal task manager? Non e' significativo
come ti e' stato detto.
Se provi a mettere le tue convinzioni da parte e volerti fidare che la
memoria viene deallocata, forse allora risulta piu' semplice farti
vedere come e perche'.
Potresti ad esempio usare una std::list<MyCounter,MyAllocator> per
osservare con comodo output a console come gli oggetti vengano distrutti
e la memoria deallocata.


 vedere come e perche'.
si avete ragione, facendo questa prova
for(int i= 0;i<200;i++)
{
      a = new MiaClasse();
      a->metodo1();
      delete a;
}
ho visto che viene deallocata e che il TM è farlocco.
ma allora quale è il metodo sicuro per vedere che non ci siano memory
leak???

 leak???
Mi rispondo da solo Borland CodeGuard ???????

allocata/deallocata???
In realtà uso molto più Delphi che C++ nel mio lavoro di tutti i
giorni e per Delphi esiste una unit molto comoda chiamata MemCheck,
che riesce a intercettare tutte le chiamate alle
allocazioni/deallocazioni riuscendo a generare un log, una volta
chiusa l'applicazione, che riporta eventuali memory leak e le linee di
codice sorgente che potrebbe averli generati.  Puoi vedere se c'è
qualcosa del genere, anche per il tuo compilatore C++.

 allocata/deallocata???
Il problema e' un altro. Quando viene deallocata della memoria questa
torna a disposizione del tuo programma, ma non e' affatto detto che
ritorni al sistema operativo.
Ciao,
Nicola

 ha scritto:

Restando OT: e' difficile che la libreria - sotto una certa soglia -
rilasci la memoria all'OS, e' piu' probabile che rimanga nel pool
dell'allocatore; cambiare i mapping e' un'operazione costosa. In questo
caso non vedresti comunque una variazione dell'address space usato dal
processo.
L'unico metodo sicuro per seguire il comportamento dell'allocatore e'
usare le funzioni di debug specifiche della libreria in uso.
Luca
-- 
Home: 
http://kronoz.cjb.net
Se non sei parte della soluzione, allora sei parte del problema.

 processo.
Questo è evidente, ma, se proprio vogliamo usare il TM, almeno guardiamo 
il valore giusto, no? Per i leak abbastanza consistenti (1 MB per es.) è 
sufficiente. Volevo soltando dire questo.
Per il mio progetto mi sono creato una piccola libreria di monitoring 
che mi segnala la presenza di leak, allocazioni/deallocazioni spaiate, 
ecc... Figurati se mi affido al TM! :-)
Kiuhnm

 ecc... Figurati se mi affido al TM! :-)
LOL, pare tutti i programmatori prima o poi finiscano con il creare la
propria libreria di debug delle allocazioni dinamiche :D
Luca
-- 
Home: 
http://kronoz.cjb.net
Pare che gli uomini facciano l'amore di continuo e le donne solo
raramente. Ci dev'essere qualcuno che bara.

Per i leak abbastanza consistenti [...]
Non ha senso parlare di "leak abbastanza consistente".