Garbage collection and ustruct

Hello. So Here is my ustruct:

USTRUCT(BlueprintType)
struct FTilePathArray
{
	GENERATED_BODY()

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	int32 StartTile;
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	TArray<int32> SimpleReachableTiles;
	UPROPERTY()
	TMap<int32, FTilePathData> ReachableTiles;

	//Constructor
	FTilePathArray() {}

};

Plase take note that TMap holds another ustruct in it.
This Ustruct is used as a return type of my function wich then assigns it to UProperty:

//in .h file:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "GridLogic")
FTilePathArray PasableArray;

UFUNCTION()
	FTilePathArray GetReachableTilesForPawnFromCell(class AGridPawnBase* pawn, int32 StartCell, int32 MoveRange, bool SimplePath);

//somewhere in .cpp code:

PasableArray = GetReachableTilesForPawnFromCell(...)

What I want to ask is how do I propertly dispose this struct before assigning a new one? I mean should I somehow “NULL” each of FTilePathData in ReachableTiles and then somehow “NULL” this structure or will itbe automatically garbage collected if there are no pointers left to it? Also, as far as I know you can not just assign NULL to struct so if I need to clean it somehow - can you please provide me an example on how to do this? Ive got not much exp in c++ programming as have not done this for last 5 years so have forgotten some basic things. Thank you for your help!

You got that right: struct variables are not NULLable.

But don’t worry about assigning a new struct on that variable. The arrays will delete themselves because of their destructor operators that will be called when their structs are destructed. If there were native pointers somewhere, created with the new keyword, or the arrays contained pointers, then you should start to worry about cleanup. Unless those pointers were initialized with NewObject() and their type was derived from UObject. Then, they’d get GC’ed once every minute or so.

As I understand, TArray and TMap are like any struct. If you have a variable of it and it’s replaced or goes out of scope, it’s instantly destroyed.

As I understand made it look like I was not sure. So I made a quick research to remember why I understand it like that.

If you pass a TArray as a value to a function, it gets copied, together with all of it’s elements. So Epic advice us to pass it as reference. It makes it clear that it works like any type and is destroyed normally, together with it’s elements.

Thank you for your answers!
And the las one I hope: here is a struct with an array of spawned object pointers:
struct FHighLightArray
{
GENERATED_BODY()

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	TArray<UDecalComponent*> PathDecals;
	//Constructor
	FHighLightArray() {}

};

Should I clean this THIS WAY:

struct FHighLightArray
{
	GENERATED_BODY()

	UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
	TArray<UDecalComponent*> PathDecals;

	void Destroy()
	{
		PathDecals.Empty();
	}
	//Constructor
	FHighLightArray() {}

};

or should I do a for loop and force each pointer to be NULL? Also will the Destroy() be called by GC automatically or I should call it manually before assigning a new value to it?

TArray.Empty will be called automatically when the struct gets destroyed. You can call it just to be sure (I do that XD). But that (or setting all of them to NULL) only destroys the pointers to those Actors, not their memory directly. So, if you don’t call Destroy on each spawned Actor manually, they won’t be GC’ed as the Level still holds references to their memory. You’ll see that even if you Empty the array (destroying all those pointers) they’ll still be alive on the level.

Be careful though: if there are other classes with references to those Actors, those references will become invalid after they’re destroyed. So, before accessing any Actor’s methods/variables, always check for it’s IsValidLowLevel() (and if it’s NULL before that, of course).