EXCEPTION_ACCESS_VIOLATION on GetSocketTransform

All,
I’m stumped and hopefully a kind soul can tell me what I am missing.

I am seeing an Error: Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff on this line of code:

for (int Index = 0; Index < Elements.Num(); Index++)
{
	if (IsValid(Elements[Index].SupportComp))
	{
		FName BoneName = Elements[Index].LastHit.BoneName;
		// this next line crashes
		FTransform SupportCompCurrentTransform = Elements[Index].SupportComp->GetSocketTransform(BoneName);

Elements is an array of USTRUCT. This USTRUCT is initialized with:

USTRUCT()
struct GAME_API FElement
{
	GENERATED_USTRUCT_BODY()

public:
	FHitResult LastHit;
	UPrimitiveComponent* SupportComp = nullptr;
};

SupportComp gets populated in a different part of the code like this:

UPrimitiveComponent* SupportComp = Hit.GetComponent();
if (IsValid(SupportComp))
{
	Elements[Index].SupportComp = SupportComp;

Where Hit is a HitResult.

This is a random crash which might take 5-10 minutes of gameplay before appearing. There are around 200 actors which run this code on tick, inside of a Custom Anim Node.

Given that I’m checking for Elements[Index].SupportComp's validity, why do you think I’m having an error on Elements[Index].SupportComp->GetSocketTransform(BoneName)?

Thanks for any input you might have,
r.

1 Like

Probably an issue with GC.
This could fix your problem:

USTRUCT()
struct GAME_API FElement
{
	GENERATED_USTRUCT_BODY()

public:
    UPROPERTY()
	FHitResult LastHit;
    UPROPERTY()
	UPrimitiveComponent* SupportComp = nullptr;
};
2 Likes

Thank you Ramon for taking some time for this, appreciated :slight_smile: Could you tell me why this might be needed? I’m gonna try it out asap but I’m curious to understand why this might make a difference.

EDIT: a little googling brought me to this, so it’s probably why you’re telling me to insert that as well:

However they refer to pointers for AActor or UActorComponent and I might have missed the UPrimitiveComponent references.

3 Likes

Any property that is not marked with UPROPERTY() can be garbage collected at any time. When you add UPROPERTY() to your property, it is associated with the object (that holds the property), and if that object is still alive, the property survives the GC :stuck_out_tongue:

2 Likes

Thank you Ramon. I’ll try this ASAP and report back (hopefully for others’ benefit as well :slight_smile: ).

1 Like

It seems that adding UPROPERTY to objects and pointers solved it.

For completeness, I also ensured to set the SupportComp to nullptr in case of an invalid return:

UPrimitiveComponent* SupportComp = Hit.GetComponent();
if (IsValid(SupportComp))
{
	Elements[Index].SupportComp = SupportComp;
}
else
{
	Elements[Index].SupportComp = nullptr;
}

Thank you!

2 Likes