La gestión de memoria es un aspecto crucial en el desarrollo de videojuegos, especialmente cuando se trabaja con un motor tan potente como Unreal Engine. En este módulo, aprenderás cómo manejar la memoria de manera eficiente en C++ dentro de Unreal Engine, lo que te permitirá crear juegos más optimizados y con mejor rendimiento.

Conceptos Clave

  1. Memoria Dinámica vs. Memoria Estática:

    • Memoria Estática: Se asigna en tiempo de compilación y su tamaño no cambia durante la ejecución del programa.
    • Memoria Dinámica: Se asigna en tiempo de ejecución y puede cambiar de tamaño según las necesidades del programa.
  2. Punteros y Referencias:

    • Punteros: Variables que almacenan la dirección de memoria de otra variable.
    • Referencias: Alias para otra variable, más seguras y fáciles de usar que los punteros.
  3. Gestión de Memoria en C++:

    • new y delete: Operadores para asignar y liberar memoria dinámica.
    • Smart Pointers: Punteros inteligentes que ayudan a gestionar la memoria automáticamente.
  4. Garbage Collection:

    • Unreal Engine utiliza un sistema de recolección de basura para gestionar la memoria de los objetos UObjects.

Asignación y Liberación de Memoria

Asignación de Memoria

En C++, puedes asignar memoria dinámica utilizando el operador new. Aquí hay un ejemplo básico:

int* myInt = new int; // Asigna memoria para un entero
*myInt = 10; // Asigna el valor 10 a la memoria asignada

Liberación de Memoria

Es crucial liberar la memoria asignada dinámicamente para evitar fugas de memoria. Esto se hace con el operador delete:

delete myInt; // Libera la memoria asignada
myInt = nullptr; // Evita punteros colgantes

Ejemplo Completo

#include <iostream>

int main() {
    int* myInt = new int; // Asigna memoria para un entero
    *myInt = 10; // Asigna el valor 10 a la memoria asignada

    std::cout << "Valor: " << *myInt << std::endl; // Imprime el valor

    delete myInt; // Libera la memoria asignada
    myInt = nullptr; // Evita punteros colgantes

    return 0;
}

Punteros Inteligentes (Smart Pointers)

Unreal Engine recomienda el uso de punteros inteligentes para gestionar la memoria de manera más segura y eficiente. Los punteros inteligentes se encuentran en la biblioteca estándar de C++ (<memory>).

Tipos de Punteros Inteligentes

  1. std::unique_ptr: Posee la memoria y la libera cuando el puntero sale de su ámbito.
  2. std::shared_ptr: Permite múltiples propietarios de la misma memoria, liberándola cuando el último propietario se destruye.
  3. std::weak_ptr: Referencia no propietaria a un std::shared_ptr.

Ejemplo de std::unique_ptr

#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> myInt = std::make_unique<int>(10); // Asigna y gestiona memoria

    std::cout << "Valor: " << *myInt << std::endl; // Imprime el valor

    // No es necesario liberar la memoria manualmente
    return 0;
}

Gestión de Memoria en Unreal Engine

UObjects y Garbage Collection

Unreal Engine utiliza un sistema de recolección de basura para gestionar la memoria de los objetos derivados de UObject. Esto simplifica la gestión de memoria, pero es importante entender cómo funciona para evitar problemas de rendimiento.

Creación de UObjects

UCLASS()
class MYGAME_API AMyActor : public AActor {
    GENERATED_BODY()

public:
    AMyActor();
};

AMyActor::AMyActor() {
    // Constructor
}

Referencias Inteligentes en Unreal Engine

Unreal Engine proporciona sus propias clases de punteros inteligentes, como TSharedPtr y TWeakPtr.

Ejemplo de TSharedPtr

TSharedPtr<int32> MySharedInt = MakeShareable(new int32(10));

Ejercicios Prácticos

Ejercicio 1: Asignación y Liberación de Memoria

  1. Asigna memoria para un array de enteros de tamaño 5.
  2. Asigna valores a cada elemento del array.
  3. Imprime los valores del array.
  4. Libera la memoria asignada.

Solución

#include <iostream>

int main() {
    int* myArray = new int[5]; // Asigna memoria para un array de enteros

    for (int i = 0; i < 5; ++i) {
        myArray[i] = i * 10; // Asigna valores
    }

    for (int i = 0; i < 5; ++i) {
        std::cout << "Valor: " << myArray[i] << std::endl; // Imprime valores
    }

    delete[] myArray; // Libera la memoria asignada
    myArray = nullptr; // Evita punteros colgantes

    return 0;
}

Ejercicio 2: Uso de std::unique_ptr

  1. Crea un std::unique_ptr para un entero.
  2. Asigna un valor al entero.
  3. Imprime el valor.

Solución

#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> myInt = std::make_unique<int>(20); // Asigna y gestiona memoria

    std::cout << "Valor: " << *myInt << std::endl; // Imprime el valor

    // No es necesario liberar la memoria manualmente
    return 0;
}

Conclusión

La gestión de memoria es un aspecto fundamental en el desarrollo de videojuegos con Unreal Engine. Comprender cómo asignar y liberar memoria, así como utilizar punteros inteligentes, te permitirá crear aplicaciones más eficientes y robustas. En el próximo módulo, exploraremos el multithreading y cómo puede mejorar el rendimiento de tu juego.

© Copyright 2024. Todos los derechos reservados