[C con Clase] En relación a Shared_Ptr y memory leaks

Miguel Ángel Torres Fernández-Píñar miguelangeltorresfp en gmail.com
Dom Dic 29 19:20:51 CET 2013


Muchas gracias Steven.

Voy a tratar de asimilarlo con calma.

Como siempre una gran explicación.

Muchísimas gracias una vez más por tu dedicarnos tu valioso tiempo.


El 29 de diciembre de 2013, 18:30, Davidson, Steven <srd4121 en njit.edu>escribió:

> Hola Miguel Ángel,
>
> 2013/12/29 Miguel Ángel Torres Fernández-Píñar <
> miguelangeltorresfp en gmail.com>
>
>> Buenos días a todos.
>>
>> Me han recomendado usar mejor punteros inteligentes ( Shared_Ptr ) para
>> miembros de una clase, para evitar memory leaks, sobre todo en casos en el
>> que tenga que cargar imágenes, textos, etc..
>>
>> Me dicen además que de esta forma puedo crear estos objetos en el momento
>> en el que me convenga. Que no se tienen que crear cuando instancio un
>> objeto de la clase.
>>
>> Me comentan que debo evitar crear objetos con el operador "new".
>>
>> Pero sigo sin tener todo esto muy claro.
>>
>>
> La idea es reducir la posibilidad de cometer errores durante la
> programación. El problema de usar memoria dinámicamente adjudicada es que
> tienes que liberarla. Si uno no tiene cuidado, o simplemente no tiene
> control acerca del momento de perder esa dirección de memoria, entonces
> perdemos la oportunidad de liberar esa memoria. A esto lo llamamos "fuga de
> memoria" (o en inglés, memory leak).
>
> Existen varias clases-plantilla, que principalmente son: 'shared_ptr',
> 'unique_ptr' (previamente, 'auto_ptr'), y 'weak_ptr' que sirven para
> representar punteros agregando algún "grado" de seguridad. Con esto,
> podemos crear un sistema de gestión de memoria que posiblemente tenga una
> "recogida de basura" (en inglés, garbage collection), que alivia el
> problema y peligro de las fugas de memoria, automatizando la liberación de
> memoria previamente adjudicada dinámicamente. Por ello, a estas
> clases-plantilla se llaman "punteros inteligentes".
>
> El caso de 'shared_ptr' sirve para compartir una misma dirección de
> memoria dinámicamente adjudicada entre varios objetos. Eso sí, la
> liberación de tal memoria recae en cada objeto; típicamente, el destructor
> por defecto liberará la memoria, pero sólo cuando sea el último y no
> comparta con otros objetos. Dicho esto, 'shared_ptr' actúa más como el
> patrón de la fábrica, compartiendo la misma dirección de memoria, pero
> tomando nota de la cuenta de objetos que la comparten. Cuando la cuenta sea
> 0 (cero), y por tanto no haya dueños de tal dirección de memoria, entonces
> se libera tal memoria.
>
> Por ejemplo, si tengo un miembro de tipo "string", ¿ debería  de usar
>> "Shared_Ptr<string>" ???
>>
>>
> No, porque el miembro es un objeto de la clase 'string', no un puntero a
> 'string'. Si tuvieras esto:
>
> class Nombre
> {
> private:
>   string *pNombre;
>
>   Nombre( const string &nom )
>   {
>     pNombre = new string( nom );
>   }
>   ~Nombre()  { delete pNombre; }
> };
>
> Entonces sí podrías usar 'shared_ptr<string>'; esto es,
>
> class Nombre
> {
> private:
>   shared_ptr<string> spNombre;
>
>   Nombre( const string &nom )
>   {
>     spNombre = make_shared<string>( new string( nom ) );
>   }
> };
>
> Siempre nos interesa construir el puntero compartido; así que haz esto:
>
> shared_ptr<int> sp = new int;
>
> Si no, entonces usa 'make_shared' para seguir esta práctica.
>
> Y en el caso de un vector de objetos de tipo "X", o de un vector " que
>> contiene otro vector de objetos de tipo "X" ?
>>
>>
> Es el mismo ejemplo anterior, si no escribes objetos dinámicamente
> adjudicados, entonces no necesitas punteros y por tanto no necesitas
> punteros inteligentes. Ciertamente, la clase-plantilla 'vector' sí usa
> memoria dinámica, pero eso no es tu problema, sino el de 'vector'. Por
> ejemplo,
>
> vector< vector<int> > vvi;
>
> vvi.push_back( vector<int>(100) );  // Crea un vector que reserva 100
> enteros y agrégalo a 'vvi'.
>
> Ahora bien, si se trata de un vector de vectores dinámicos, entonces sí
> usaríamos un puntero inteligente; por ejemplo,
>
> vector< unique_ptr< vector<int> > > vpvi;
>
>
> Espero que esto te aclare las dudas.
>
> Steven
>
>
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20131229/705011c7/attachment.html>


Más información sobre la lista de distribución Cconclase