How does TArray keep references? My custom container is getting it's elements garbage collected

I’m implementing a generic Octree structure, and I can’t make a template class a UClass (UHT freaks out) or the data a UPROPERTY. So my question is, how do I store a pointer to a UObject class and prevent the GC from collecting it? TArray gets away with this, but I can’t find any relevant code that makes it work.

1 Like

TArray only works when marked as a UPROPERTY, and in those cases the reflection system does handle it for you.

For non-uproperty types, you need to manage this manually. The standard approach is to add a AddReferencedObjects function to your structure, and then users of that structure in their own AddReferencedObjects function call that. If you search through the code base for AddReferencedObjects you’ll find many examples.

1 Like

Ok.

How is TArray allowed to be marked as a UPROPERTY? When I try to mark my octree, it says the type is unrecognized.

TArray is specifically integrated in as a base property type, adding new types is a very involved process and adding TMap has been a long ongoing process, it would not be recommended that you take that approach.

Anything that is a USTRUCT can be a property, so that may be an option for you, but otherwise you just have to manually wire it in to the AddReferencedObject system.

1 Like

Alright, thanks.

Good thing to know I wasnt the only 1 with this issue, so from what I understand I cant use TARRAY for referencing custom types; in which case I have to use AddReferencedObjects container.

How would I go about using it for something dynamic like this:

Sorry to necropost, but is this still true? The Garbage Collection documentation says:

One practical implication here is that you typically need to maintain a UPROPERTY reference to any Object you wish to keep alive, or store a pointer to it in a TArray or other Unreal Engine container class.

This doesn’t explicitly say a TArray member itself needs to be a UPROPERTY. The or store a pointer to in in a TArray part implies that simply storing it in any old TArray (marked UPROPERTY or not) is sufficient to prevent elements from being GC’d. That said, there appears to be nothing inside the TArray itself that knows about GC, so it appears that the UPROPERTY reflection macro is still required.

The TArray still has to be marked as a UPROPERTY. The GC logic, loosely, goes like this:

For each UObject...
   For each UProperty in the Object...
       If UProperty is an array type
           Mark each Array entry as still in use.

Meaning, it all goes through the reflection system. So, unless you mark the TArray itself as a UPROPERTY - the GC system has no idea about it, or its contents.

2 Likes