Managed memory – using NewObject< > and ConstructObject< >

Managed memory refers to memory that is allocated and deallocated by some programmed subsystem above the new, delete, malloc, and free calls in C++. These subsystems are commonly created so that the programmer does not forget to release memory after allocating it. Unreleased, occupied, but unused memory chunks are called memory leaks. For example:

for( int i = 0; i < 100; i++ )
int** leak = new int[500]; // generates memory leaks galore!

In the preceding example, the memory allocated is not referenceable by any variable! So you can neither use the allocated memory after the for loop, nor can you free it. If your program allocates all available system memory, then what will happen is that your system will run out of memory entirely, and your OS will flag your program and close it for using up too much memory.

Memory management prevents forgetting to release memory. In memory-managed programs, it is commonly remembered by objects that are dynamically allocated the number of pointers referencing the object. When there are zero pointers referencing the object, it is either automatically deleted immediately, or flagged for deletion on the next run of the garbage collector.

Use of managed memory is automatic within UE4. Any allocation of an object to be used within the engine must be done using NewObject< >() or SpawnActor< >(). The release of objects is done by removing the reference to the object, then occasionally calling the garbage cleanup routine (listed further in this chapter).

Getting ready

When you need to construct any UObject derivative that is not a derivative of the Actor class, you should always use NewObject< >. SpawnActor< > should be used only when the object is an Actor or its derivative.

How to do it...

Say we are trying to construct an object of type UAction, which itself derives from UObject. For example, the following class:

UCLASS(BlueprintType, Blueprintable, meta=(ShortTooltip="Base class for any Action type") )
Class WRYV_API UAction : public UObject
{
  GENERATED_UCLASS_BODY()
  public:
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Properties)
  FString Text;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Properties)
  FKey ShortcutKey;
};

To construct an instance of the UAction class, we'd do the following:

UAction* action = NewObject<UAction>( GetTransientPackage(),
UAction::StaticClass() /* RF_* flags */ );

How it works…

Here, UAction::StaticClass() gets you a base UClass* for the UAction object. The first argument to NewObject< > is GetTransientPackage(), which simply retrieves the transient package for the game. A package (UPackage) in UE4 is just a data conglomerate. Here we use the Transient Package to store our heap-allocated data. You could also use UPROPERTY() TSubclassOf<AActor> from Blueprints to select a UClass instance.

The third argument (optional) is a combination of parameters that indicate how UObject is treated by the memory management system.

There's more…

There is another function very similar to NewObject< > called ConstructObject< >. ConstructObject< > provides more parameters in construction, and you may find it useful if you need to specify these parameters. Otherwise, NewObject works just fine.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.81.154