Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Developer Diego en 19 Mayo 2014, 06:16 am



Título: Memoría dinámica
Publicado por: Developer Diego en 19 Mayo 2014, 06:16 am
La memoria dinámica es aquella que se puede cambiar en tiempo de ejecución, el stdlib (la librería estándar de C++) nos permite usar funciones como malloc, calloc, realoc, free, ahora estoy estudiándolo para estructuras de datos que se ejecutan en la memoria dinámica, pero en C++ a diferencia de C, yo puedo usar el puntero inteligente (Smart pointer) new y delete como un free.

Ahora la cuestión es: Será mejor usar las funciones de la librería stl o los operadores new y delete.
Básicamente new puede trabajar con cualquier tipo de dato (Esto nos dice que trabaja con el tipo de dato void).


Título: Re: Memoría dinámica
Publicado por: eferion en 19 Mayo 2014, 08:58 am
Son diferentes.

new y delete te dan un control muy preciso sobre el ciclo de vida de los objetos... pero ese control tiene un precio a pagar y es que vas a tener que estar muy pendiente para evitar lagunas de memoria.

los smart pointers son una característica bastante interesante de la stl. Te permite relajarte en la gestión de la memoria dinámica a costa de perder cierto control sobre el ciclo de vida de los objetos. Yo, a título personal, únicamente soy partidario de usar unique_ptr, ya que con shared_ptr el concepto de "ciclo de vida" queda demasiado difuso.

También recordar que shared_ptr puede provocar lagunas de memoria si creas relaciones circulares... y usar weak_ptr es, a veces, un coñazo


Título: Re: Memoría dinámica
Publicado por: Developer Diego en 20 Mayo 2014, 05:20 am
Pero los smarts pointer saben liberarse en el tiempo adecuado, cuando ya no son referenciados en memoria, por el mismo ciclo de vida de los objetos.


Título: Re: Memoría dinámica
Publicado por: eferion en 20 Mayo 2014, 08:25 am
Este ejemplo te demostrará que un diseño incorrecto con smart pointers puede acabar con lagunas de memoria:

Código
  1. #include <iostream>
  2. #include <memory>
  3.  
  4. class Nodo
  5. {
  6.    static int id;
  7.  
  8.  public:
  9.    Nodo( )
  10.      : _id( id++ )
  11.    {  std::cout << "Nodo " << id << " creado" << std::endl; }
  12.  
  13.    ~Nodo( )
  14.    { std::cout << "Nodo " << id << " destruido" << std::endl; }
  15.  
  16.    std::shared_ptr< Nodo > puntero;
  17.  
  18.  private:
  19.  
  20.    int _id;
  21. };
  22.  
  23. int Nodo::id = 0;
  24.  
  25. void func( )
  26. {
  27.    std::shared_ptr< Nodo > nodo1 = std::make_shared< Nodo >( );
  28.    std::shared_ptr< Nodo > nodo2 = std::make_shared< Nodo >( );
  29.    std::shared_ptr< Nodo > nodo3 = std::make_shared< Nodo >( );
  30.  
  31.    nodo1->puntero = nodo2;
  32.    nodo2->puntero = nodo1;
  33. }
  34.  
  35. int main( )
  36. {
  37.  std::cout << "Llamada a func" << std::endl;
  38.  
  39.  func( );
  40.  
  41.  std::cout << "Y la llamada a los destructores de nodo1 y nodo2?" << std::endl;
  42. }

Efectivamente, un shared_ptr está diseñado para borrar su contenido cuando éste ya no esté referenciado... el problema es que, si se crean referencias circulares, se crea una dependencia mutua que impide que los elementos se borren.


Título: Re: Memoría dinámica
Publicado por: Developer Diego en 20 Mayo 2014, 23:10 pm
Buenas tardes, muchas gracias por resolver mi duda, me quedo claro qué es lo más eficiente para el manejo de memoria.