If you need a TArray to be initialized with certain values, here is how to do it:
TArray <int32> MyInt32Array
{
{2},
{4},
{8}
};
Bonus: if you wan't to initialize the Array and be sure, it's initialized properly without any values, you may use "{}" (see below).
TArray <int32> MyInt32Array {};
Using pointers this could, in theory, prevent certain errors like "not properly initialized", though maybe just by the compiler.
Variant A:
TArray <int32> MyInt32Array;
if you're using the array immediately afterwards (.Add, .Reserve etc.)
if this is extremely performance critical (every operation counts)
Variant B:
TArray <int32> MyInt32Array {};
if you wanna make it clear, that the array is empty at the point of inizialization
if you want to avoid eventual garbage values inside
If you want to fill an entire TArray with values and already pre-allocate a certain amount of memory for its length, use:
TArray <int32> MyInt32Array;
MyInt32Array.Init(42, 12); // the value "42" will be added "12" times, giving the array a length of 12
If you want to create a dynamic TArray on the heap, but make sure it's as performant as a static array afterwards, use:
TArray <int32> MyInt32Array;
MyInt32Array.Reserve(12);
This...
will only reserve the right amount of memory, so you can easily add new elements and it won't expand automatically until it hits > 12 elements.
will prevent too many changes to the heap
is compatible with pretty much all array based functions/methods within Unreal Engine
To reduce any action that happens on the heap, this setting is extremely important. Let's look at the following example:
TArray <AActor*> Actors;
Actors.Reserve(8);
Here we have told Unreal to create a dynamic array that is stored on the heap and then allocating space for up to 8 elements. If we add more, the size will increase dynamically causing dynamic memory allocation on the heap.
Now let's say, we added some AActor* Actors and later, we want to remove an Actor at a certain index.
Actors.RemoveAt(3);
This will remove the stored pointer to the actor, but it will also shrink the DYNAMIC ARRAY. Meaning: de- and re-allocation on the heap. Why?
Actors.RemoveAt(3, EAllowShrinking::Yes);
As you can see, "EAllowShrinking" is a default setting, that is set to yes.
So what can we do to keep our Array at a size of 8 while not having to do anything on the heap?
Actors.RemoveAt(3, EAllowShrinking::No);
So as a lesson: If you want to remove an Element from an Array without reducing the Arrays' allocated size, always make sure to disallow shrinking whenever possible. This may, depending on the circumstance, save a lot of performance and reduce hitching.
The regular TArray is a dynamically managed Array, meaning it is stored on the Heap.
However, sometimes you know it usually won't exceed a maximum amount of entries, hence storing on the Stack could improve performance.
Especially for using Arrays in functions, it could save some performance. To make use of it:
TArray <AActor*, TInlineAllocator<32>> MyActorArray {};
Now the maximum size of the Array is 32 and it will be stored on the Stack. Additionally, if the size is exceeded, a the Array will be converted into a dynamic one.
This...
... will store it's data on the Stack and save performance.
... may be better than a C-Style array, due to various validity checks and memory management by Unreal Engines' framework.
... can exceed the maximum size, but will then become a dynamic array being stored on the heap.
... does NOT work with UPROPERTY!
... should probably not be used with very large Arrays or ones, where the size may easily be exceeded.
**untested
The regular TArray is a dynamically managed Array, meaning it is stored on the Heap.
However, sometimes you know it won't exceed a maximum amount of entries, hence storing on the Stack could improve performance.
Especially for using Arrays in functions, it could save some performance. To make use of it:
TArray <AActor*, TFixedAllocator<32>> MyActorArray {};
Now the maximum size of the Array is 32 and it will be stored on the Stack and it can NOT be exceeded!
This...
... will store it's data on the Stack and save performance.
... may be better than a C-Style array, due to various validity checks and memory management by Unreal Engines' framework.
... must have checks to prevent it from overflowing (index counter or an if check like MyActorArray.Num() < MyActorArray.Max()**)
... does NOT work with UPROPERTY!
... should probably not be used with very large Arrays or ones, where the size may easily be exceeded.