PDA

View Full Version : perdita di memoria C++, non riesco a capire una cosa credo semplice..


cudido
27-07-2016, 23:58
Buonaseraa :)

C'č una cosa che mi sta facendo immattire:

Uso queste due righe per immettere un elemento in una lista e poi per cancellarlo:

listaSchermata.back().inserisci_boxTesto(...)
listaSchermata.back().listaBoxTesto.pop_back();


che richiama questa

void schermata::inserisci_boxTesto(int x_, int y_, int l_, int a_, texture* textureFont_, int tipoSfondo, texture* textureInterfaccia)
{
boxTesto* pB = new boxTesto(x_, y_, l_, a_, textureFont_, tipoSfondo, textureInterfaccia);
listaBoxTesto.push_back(*pB);
pboxTestoAttivo = &listaBoxTesto.back();
}

dopo questa riga ho in pių 6,41K usati di memoria
boxTesto* pB = new boxTesto(x_, y_, l_, a_, textureFont_, tipoSfondo, textureInterfaccia);

dopo questa ho altri 6,47K usati di memoria
listaBoxTesto.push_back(*pB);


ritorno alla funzione di prima, eseguo

listaSchermata.back().listaBoxTesto.pop_back();

e mi vengono liberati solo 6,47K !

Premetto che se creo un oggetto boxTesto e poi lo cancello senza metterlo nella lista si libera la memoria correttamente.

Ci sto immattendo! Cosa sbaglio?

Grazie :)

:muro:

cudido
28-07-2016, 00:49
http://www.cplusplus.com/reference/list/list/push_back/

Adds a new element at the end of the list container, after its current last element. The content of val is copied (or moved) to the new element

mentre tu con questa linea

boxTesto* pB = new boxTesto(x_, y_, l_, a_, textureFont_, tipoSfondo, textureInterfaccia);


allochi nell'heap un nuovo elemento che non viene deallocato automaticamente.

Puoi risolvere semplicemente sostituendo quella linea con

boxTesto B(x_, y_, l_, a_, textureFont_, tipoSfondo, textureInterfaccia);
listaBoxTesto.push_back(B);


Ero rientrato nel forum per dire che avevo risolto, ero abituato alle liste "a mano" :D comunque grazie mille :)

fano
28-07-2016, 09:51
In generale siccome C++ non ha il Garbage Collector come tutti i linguaggi di programmazione moderni č sempre meglio evitare l'operatore new e quindi allocare gli oggetti nello stack cosė almeno si mitiga un po' il problema dei memory leak.

71106
28-07-2016, 16:58
In generale siccome C++ non ha il Garbage Collector come tutti i linguaggi di programmazione moderni č sempre meglio evitare l'operatore new e quindi allocare gli oggetti nello stack cosė almeno si mitiga un po' il problema dei memory leak. Un programma C++ scritto decentemente non contiene praticamente nessuna chiamata all'operatore new. E' preferibile usare scoped objects come unique_ptr (http://en.cppreference.com/w/cpp/memory/unique_ptr).

71106
28-07-2016, 17:02
E' preferibile usare scoped objects come unique_ptr (http://en.cppreference.com/w/cpp/memory/unique_ptr). Voglio dire quando ovviamente non sia possibile allocare semplicemente sullo stack come hai notato tu.

I casi in cui l'allocazione statica non e' possibile non sono tanto rari, comunque. Un paio di esempi:

strutture dati induttive il cui contenuto e' determinato a runtime, p.es. alberi e liste;
risorse il cui ciclo di vita non e' associato allo scope corrente, p.es. oggetti dal contenuto molto grande che vanno restituiti al chiamante e si vuole evitare di costruirne delle copie.