Read access violation

Hi!

I’m developing a game with Unreal Engine 5.2. and C++.

I have this structure:

USTRUCT(BlueprintType)
struct FBall
{
	GENERATED_BODY()

	[...]

	class ABallActor* BallActor;

	[...]
};

The class ABallActor has this method:

void ABallActor::HideBallActor(bool toHide)
{
	if (toHide != IsHiden)
	{
		SetActorHiddenInGame(toHide);
		SetActorEnableCollision(!toHide);
		SetActorTickEnabled(!toHide);

		IsHiden = toHide;
	}

}

I have a class that inherits from UGameInstanceSubsystem where I create all the instances of ABallActor. This method uses an instance variable to store the actors created in a TArray<FBall> TheBalls.

TheBalls is defined:

private:

	TArray<FBall> TheBalls;

And the Show method is:

void UMyGameInstanceSubsystem::Show(
	TSubclassOf<class ABallActor> BlueprintBall,
	float Radius) const
{
	TArray<AActor*> FoundActors;

	UGameplayStatics::GetAllActorsOfClass(GetWorld(), ABallsSphereActor::StaticClass(), FoundActors);

	if (FoundActors.Num() == 1)
	{
		if (ABallsSphereActor* BallsSphere = Cast<ABallsSphereActor>(FoundActors[0]))
		{
			const FAttachmentTransformRules AttachmentTransformRules =
				FAttachmentTransformRules(EAttachmentRule::KeepWorld, true);

			for (FBall& ball : TheBalls)
			{
				FVector SpawnLocation;

				[...]

				ball.BallActor = Cast<ABallActor>(
					GetWorld()->SpawnActor(BlueprintBall, &SpawnLocation));

				[...]
				ball.BallActor->AttachToActor(BallsSphere, AttachmentTransformRules);

				ball.BallActor->HideBallActor(!ball.ToShow);
			}
		}
	}
}

In the above method, ball.BallActor->HideBallActor(!ball.ToShow); works fine.

But, after showing the ball, I use HideBallActor again in another method:

void UMyGameInstanceSubsystem::Update()
{
	for (FBall& ball : TheBalls)
	{
		ball.ToShow = [...];

		if (ball.BallActor)
			ball.BallActor->HideBallActor(ball.ToShow);
	}
}

I get an exception in this sentence (inside the HideBallActor method):

if (toHide != IsHiden)

The exception is:

An exception occurred: read access violation. **this** fue 0xFFFFFFFFFFFFFBE7.

I think the problem could be storing the spawned ball actors into the TArray<FBall> TheBalls array. But, it’s strange because it works inside the Show method.

How can I fix this problem?

Thanks!

Use UPROPERTY() For UObjects.

The garbaje collertor is killing your pointers

2 Likes

Why are you using raw pointers in this situation? Where do you create an object for BallActor and is it ever destructed somewhere? Looking at the BallActor member it is never initialized which could be the reason for the access violation. I would recommend to use UE5 smart pointers instead. Smart Pointers in Unreal Engine | Unreal Engine 5.0 Documentation

1 Like

I

Because I newbie and I’m learning.

Refrain from using raw pointers and use the smart pointers instead since they do the memory management for you.

Thanks, @marwinhormiz.

Probably, I haven’t understood anything, but in the link you passed me said:

These classes cannot be used with the UObject system because Unreal Objects use a separate memory-tracking system that is better-tuned for game code.

I think AActor is an UObject, so… I don’t know how I can use Smart Pointers with an UObject.

Or, maybe I have to use a pointer in another property.

MakeSharable()
MakeShared()
TSharedPt<>
TSharedRef<>

Your struct FBall is not inheriting from an UObject therefore you can use a smart pointer for the BallActor property which is currently just a raw pointer.

I have modified this:

USTRUCT(BlueprintType)
struct FBall
{
	GENERATED_BODY()

	[...]

	UPROPERTY()
	class ABallActor* BallActor;

	[...]
};

And:

private:

	UPROPERTY()
	TArray<FBall> TheBalls;

I’m still having the same error.

But BallActor is an UOBJECT.

Okay. Well then the issue must be somewhere in the array since you are iterating through all the ball objects in the “Update” function and like @Ivan3z said before the garbage collector could be killing the pointers. You’ll pretty much have to debug it and step through your code to see where the issue is occuring and backtrace.

1 Like

Try initializing the “BallActor” property in FBall struct to nullptr and try again. So just do class ABallActor* BallActor = nullptr; The problem is that when the array “TheBalls” is constructing the FBall struct, the raw pointer within that struct is still uninitialized leading to this undefined behavior.

I’ve done it and now, here:

void UMyGameInstanceSubsystem::Update()
{
	for (FBall& ball : TheBalls)
	{
		ball.ToShow = [...];

		if (ball.BallActor)
			ball.BallActor->HideBallActor(ball.ToShow);
	}
}

ball.BallActor is NULL.

Before doing this, class ABallActor* BallActor = nullptr;, ball.BallActor had a value different from NULL.

Do you ever create an object for BallActor before adding the FBall to the array? If so, could you provide that code? (nvm I just saw you using SpawnActor)

I do it in the UMyGameInstanceSubsystem::Show method:

ball.BallActor = Cast<ABallActor>(
					GetWorld()->SpawnActor(BlueprintBall, &SpawnLocation));

And the actors appear on the level.

Would you be able to share the whole code for both header and cpp file of FBall and UMyGameInstanceSubsystem? Or you could try to set it to UPROPERTY like Ivan said aswell.

1 Like

Thanks, I set UPROPERTY and now it works.

Thanks a lot.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.