Intermittent exceptions in generated c++ class

I have a simple ability system that’s working, however I’m getting an intermittant exception from one of the unreal generated classes(PGameAbility.gen.cpp).
The exceptions only arises after using the ability something like 20+ times.
I either get an access violation or a this → was nullptr exception and the process is at the end of this function( or the CancelAbility Function):

#From the PGameAbility.gen.cpp file#

void UPGameAbility::ActivateAbility()
{
ProcessEvent(FindFunctionChecked(NAME_UPGameAbility_ActivateAbility),NULL);
->}#execution is here

I’ve debugged in VS and when that exception arises the this pointer seems to be valid and don’t see any clue as to whats even causing the nullptr exception.
The ActivateAbility function is a BlueprintNativeEvent(I’ve tried BlueprintImplenetableevent also to the same result) and I’ve tried subclassing in both blueprint and c++ but get the same exceptions.

I’m using the unreal 5.0.2 build from the epic games launcher.

Code is below, I’ve only included the relevent parts to save space. I’ve only included the jump ability below but the others work largely the same and generate the same exceptions.

This is the class the kicks off the ability

UCLASS()
class PLATFORMERPROTOTYPE_API AHeroCharacter : public APCharacterBase
{
GENERATED_BODY()

protected:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = “Ability”)
TSubclassOf JumpAbility;

private:
FGameAbilityHandle JumpHandle;

public:
AHeroCharacter(const class FObjectInitializer& ObjectInitializer);

// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;

virtual void Jump() override;
virtual void StopJumping() override;

protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;

void ActivateJumpAbility();
void CancelJumpAbility();
};

void AHeroCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);

PlayerInputComponent->BindAction(“Jump”, IE_Pressed, this, &AHeroCharacter::ActivateJumpAbility);
PlayerInputComponent->BindAction(“Jump”, IE_Released, this, &AHeroCharacter::CancelJumpAbility);
}

void AHeroCharacter::BeginPlay()
{
Super::BeginPlay();

if (GetAbilitySystem() != nullptr)
{
if(JumpAbility != nullptr)
JumpHandle = GetAbilitySystem()->AddAbility(JumpAbility, this, this);
}
}

void AHeroCharacter::ActivateJumpAbility()
{
if (JumpHandle.IsValid())
{
if (AbilitySystem != nullptr)
AbilitySystem->RunAbility(JumpHandle);
}
}

void AHeroCharacter::CancelJumpAbility()
{
if (JumpHandle.IsValid())
{
if(AbilitySystem != nullptr)
AbilitySystem->CancelAbility(JumpHandle);
}
}

#This base class stores and initialises the AbilitySystem#

UCLASS()
class PLATFORMERPROTOTYPE_API APCharacterBase : public ACharacter, public IIHasAbilitySystem, public IHasAttributes
{
GENERATED_BODY()

UPROPERTY()
UPAbilitySystem* AbilitySystem;

public:
APCharacterBase(const class FObjectInitializer& ObjectInitializer);

protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual UPAbilitySystem* GetAbilitySystem() { return AbilitySystem; }
};

void APCharacterBase::BeginPlay()
{
Super::BeginPlay();

AbilitySystem = NewObject(this, UPAbilitySystem::StaticClass(), TEXT(“AbilitySystem”));
}

#I tried creating the AbilitySystem in the constructor using createdefaultsubobject but I still get the exceptions#

UCLASS()
class PLATFORMERPROTOTYPE_API UPAbilitySystem : public UObject
{
GENERATED_BODY()

public:
UPAbilitySystem();

protected:
TMap<FGameAbilityHandle, UPGameAbility*> Abilities;

public:
FGameAbilityHandle AddAbility(TSubclassOf Ability, AActor* Owner, APawn* PawnOwner);
void RemoveAbility(FGameAbilityHandle AbilityHandle);

void RunAbility(FGameAbilityHandle Handle);
void CancelAbility(FGameAbilityHandle Handle);
};

FGameAbilityHandle UPAbilitySystem::AddAbility(TSubclassOf Ability, AActor* Owner, APawn* PawnOwner)
{
FGameAbilityHandle Handle;

if (Ability != nullptr && Owner != nullptr)
{
auto AbilityInstance = NewObject(Owner, Ability);

  AbilityInstance->SetOwner(Owner);
  AbilityInstance->SetPawnOwner(PawnOwner);

  Handle.GenerateHandle();
  Abilities.Add(Handle, AbilityInstance);

  return Handle;

}

// This returns an invalid handle
return Handle;
}

void UPAbilitySystem::RemoveAbility(FGameAbilityHandle AbilityHandle)
{
if (AbilityHandle.IsValid())
{
Abilities.Remove(AbilityHandle);
}
}

void UPAbilitySystem::RunAbility(FGameAbilityHandle Handle)
{
if (Abilities.Contains(Handle))
{
auto abilityToRun = Abilities[Handle];

  if (abilityToRun != nullptr)
  {
  	abilityToRun->RunAbility();
  }

}
}

#Cancel Ability is effectivly the same just calls a difference function.
I also tried using Abilities.Find() but still get the same issue.#

UCLASS(Blueprintable)
class PLATFORMERPROTOTYPE_API UPGameAbility : public UObject
{
GENERATED_BODY()

friend class UPAbilitySystem;

private:

bool bIsOnCooldown;
bool bIsRunning;

protected:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = “Components”)
AActor* OwningActor;

UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = “Components”)
APawn* OwningPawn;

public:
UPGameAbility();

UFUNCTION()
void RunAbility();

UFUNCTION()
AActor* GetOwningActor() { return OwningActor; }

protected:
UFUNCTION(BlueprintNativeEvent, Category = “Event”)
void ActivateAbility();

virtual void ActivateAbility_Implementation() {};

UFUNCTION(BlueprintNativeEvent, Category = “Event”)
void CancelAbility();

virtual void CancelAbility_Implementation() {};

UFUNCTION(BlueprintCallable, Category = “Event”)
void EndAbility();

private:
void SetOwner(AActor* ActorOwner);
void SetPawnOwner(APawn* PawnOwner);
};

void UPGameAbility::RunAbility()
{
if (!bIsRunning)
{
if (!bIsOnCooldown)
{
bIsRunning = true;
ActivateAbility();
}
}
}

void UPGameAbility::EndAbility()
{
bIsRunning = false;
}

#This is the C++ subclass version of the jump ability#

UCLASS()
class PLATFORMERPROTOTYPE_API UHeroJumpAbility : public UPGameAbility
{
GENERATED_BODY()

protected:
virtual void ActivateAbility_Implementation() override;
virtual void CancelAbility_Implementation() override;
};

void UHeroJumpAbility::ActivateAbility_Implementation()
{
if (CanUseAbility())
{
if (GetOwningActor() != nullptr)
{
auto HeroChar = Cast(GetOwningActor());

  	if (HeroChar != nullptr)
  	{
  		HeroChar->Jump();
  	}
  }

}
}

void UHeroJumpAbility::CancelAbility_Implementation()
{
if (GetOwningActor() != nullptr)
{
auto HeroChar = Cast(GetOwningActor());

  if (HeroChar != nullptr)
  {
  	HeroChar->StopJumping();
  }

}

EndAbility();
}

Example of one of the exceptions in (PGameAbility.gen.cpp):

The blueprint version is much the same, just in blueprint.
Can anyone see anything that might be causing this exception as I’m completely stumped.
I had an issue early on where the blueprint subclass for the HeroCharacter was setting the AbilitySystem pointer to nullptr, however Reparenting the HeroCharacter blueprint class and then reparenting back fixed that.
I tried that for this but it didn’t fix it this time for either HeroCharacter or subclasses of GameAbility.

I’m hoping it’s a simple fix that I’ve overlooked.

Long shot here, but it looks like in some places you are storing UObjects into variables/containers with no UPROPERTY specifier:

protected:
TMap<FGameAbilityHandle, UPGameAbility*> Abilities;

Without an UPROPERTY reference (or adding them to root set), your objects will get garbage collected on first occasion, causing this sort of issues.

Ahhh, thank you. Didn’t realise it was UPROPERTY that set the ref count for garbage collection.
I tried that and it did indeed fix it.