Course contentsShow
← Unreal Engine Game Development
Lesson 184 of 8803. C++ and UObject ArchitectureFree lesson

Integrating Smart Pointers with C++ Containers

Learn to store smart pointers within Unreal’s TArray and TMap containers while maintaining proper reference counting and memory safety throughout the collection.

In this lesson, you will learn how to efficiently store and manage smart pointers within Unreal Engine’s standard TArray and TMap containers to maintain memory safety and automated cleanup.

Why Use Containers with Smart Pointers?

When you manage non-UObject data—such as custom configuration structs or third-party library objects—you often need to track them in collections. While TArray and TMap are optimized for simple types, they become powerful memory-management tools when they hold TSharedPtr or TUniquePtr.

Because TSharedPtr keeps an internal reference count, storing these pointers in a TArray ensures that the objects they point to are not destroyed while they exist in the container. When an element is removed from the array or the array itself is cleared, the smart pointer’s destructor is called, automatically decrementing the reference count (or deleting the object if it was a TUniquePtr).

Implementation Example

To store shared pointers, you simply define the container type using the pointer class as the element type. Unreal’s containers are specifically designed to handle the copy/move semantics of these smart pointers:

// Storing shared pointers in an array
TArray<TSharedPtr<FMyCustomData>> DataArray;

// Adding a new object
DataArray.Add(MakeShared<FMyCustomData>(42));

// Accessing an element
if (DataArray.IsValidIndex(0))
{
    DataArray[0]->DoSomething();
}

// Removing an element triggers the reference count decrement
DataArray.RemoveAt(0); 

Critical Considerations

When using TMap, remember that the key must support hashing. While TSharedPtr works as a value, using it as a key in a TMap requires a custom hashing function, as the map needs to know how to compare the underlying pointers.

Furthermore, avoid storing TSharedPtr in a UPROPERTY. Unreal’s Garbage Collection system does not track smart pointers. If you need to store data that participates in the Reflection System, continue using raw UObject* pointers marked with UPROPERTY(). Use TArray<TSharedPtr<>> strictly for non-UObject, heap-allocated data that requires scope-based ownership rather than garbage collection.

Key Takeaway: Storing smart pointers in TArray and TMap automates memory cleanup for non-UObject data, as the container lifecycle effectively manages the smart pointer's reference count.