Memoría dinámica

Iniciado por Developer Diego, 19 Mayo 2014, 06:16 AM

0 Miembros y 1 Visitante están viendo este tema.

Developer Diego

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).
-- The code is life --
Diego De Santiago Ruiz.

eferion

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

Developer Diego

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.
-- The code is life --
Diego De Santiago Ruiz.

eferion

Este ejemplo te demostrará que un diseño incorrecto con smart pointers puede acabar con lagunas de memoria:

Código (cpp) [Seleccionar]

#include <iostream>
#include <memory>

class Nodo
{
    static int id;

  public:
    Nodo( )
      : _id( id++ )
    {  std::cout << "Nodo " << id << " creado" << std::endl; }

    ~Nodo( )
    { std::cout << "Nodo " << id << " destruido" << std::endl; }

    std::shared_ptr< Nodo > puntero;

  private:

    int _id;
};

int Nodo::id = 0;

void func( )
{
    std::shared_ptr< Nodo > nodo1 = std::make_shared< Nodo >( );
    std::shared_ptr< Nodo > nodo2 = std::make_shared< Nodo >( );
    std::shared_ptr< Nodo > nodo3 = std::make_shared< Nodo >( );

    nodo1->puntero = nodo2;
    nodo2->puntero = nodo1;
}

int main( )
{
  std::cout << "Llamada a func" << std::endl;

  func( );

  std::cout << "Y la llamada a los destructores de nodo1 y nodo2?" << std::endl;
}


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.

Developer Diego

Buenas tardes, muchas gracias por resolver mi duda, me quedo claro qué es lo más eficiente para el manejo de memoria.
-- The code is life --
Diego De Santiago Ruiz.