Error EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff with Splines

I get this Error and the Editor crashes when i try to edit spline points after a while or after restarting the project:

Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff (SplineStreet.cpp:103)

Sometimes its on line 61 but I’m not sure why. When moving the same Spline Point it sometimes is this line and sometimes the other.

The Setup is as follows:
An Editable SplineComponent is the core component. On it SplineMeshComponents get added and two splines (curbs): one on the right, the other on the left side. They then get points assigned based on the MainSpline’s SplinePoints:

.cpp

#include "SplineStreet.h"
#include "Components/SplineComponent.h"
#include "Components/SplineMeshComponent.h"
#include "Components/TextRenderComponent.h"


// Sets default values
ASplineStreet::ASplineStreet()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;

	MainSpline = CreateDefaultSubobject<USplineComponent>(TEXT("MainSpline"));
	MainSpline->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);

	LeftCurbSpline = CreateDefaultSubobject<USplineComponent>(TEXT("LeftCurb"));
	LeftCurbSpline->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
	LeftCurbSpline->CreationMethod = EComponentCreationMethod::UserConstructionScript;

	RightCurbSpline = CreateDefaultSubobject<USplineComponent>(TEXT("RightCurb"));
	RightCurbSpline->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
	RightCurbSpline->CreationMethod = EComponentCreationMethod::UserConstructionScript;	

	if (RoadMesh)
	{
		//set initial spline length to be exactly the size of one mesh
		MainSpline->SetLocationAtSplinePoint(1, FVector(RoadMesh->GetBoundingBox().GetExtent().X * 2, 0, 0), ESplineCoordinateSpace::Local);
	}
}



// Called when the game starts or when spawned
void ASplineStreet::BeginPlay()
{
	Super::BeginPlay();
}



void ASplineStreet::OnConstruction(const FTransform& Transform)
{
	if (RoadMesh) {
		float Length = MainSpline->GetSplineLength();
		float MeshHalfLength = RoadMesh->GetBoundingBox().GetExtent().X;
		float MeshLength = MeshHalfLength * 2;

		int32 NumOfMeshes = FMath::CeilToInt32(Length / MeshLength);

		float SegmentLength = Length / NumOfMeshes;

		//create all spline meshes for the road
		PopulateMeshAlongSpline(MainSpline, RoadMesh);


		//remove all points from curb splines
		const int32 LeftNum = LeftCurbSpline->GetNumberOfSplinePoints();
		for (int32 i = 0; i < LeftNum ; i++)
		{
			LeftCurbSpline->RemoveSplinePoint(i);
		}
		
		const int32 RightNum = RightCurbSpline->GetNumberOfSplinePoints();
		for (int32 i = 0; i < RightNum; i++)
		{
			 RightCurbSpline->RemoveSplinePoint(i);
		}
		
		
		//add spline points to curb splines
		for (int32 i = 0; i < MainSpline->GetNumberOfSplinePoints(); i++)
		{
			FVector Tangent = MainSpline->GetTangentAtSplinePoint(i, ESplineCoordinateSpace::Local);
			FVector LeftVec = Tangent.RotateAngleAxis(270.f, FVector(0, 0, 1));
			FVector RightVec = Tangent.RotateAngleAxis(90.f, FVector(0, 0, 1));

			LeftVec.GetSafeNormal();
			LeftVec.Normalize();
			RightVec.GetSafeNormal();
			RightVec.Normalize();

			float MeshHalfWidth = RoadMesh->GetBoundingBox().GetExtent().Y;

			FVector RightOffset = RightVec * (MeshHalfWidth);// + CurbWidth);
			FVector LeftOffset = LeftVec * MeshHalfWidth;

			FVector PosAtPoint = MainSpline->GetLocationAtSplinePoint(i, ESplineCoordinateSpace::World);
			FVector NewPosLeft = PosAtPoint + LeftOffset; //+ RootComponent->GetComponentLocation();
			FVector NewPosRight = PosAtPoint + RightOffset; //+ RootComponent->GetComponentLocation();

			if (i < LeftCurbSpline->GetNumberOfSplinePoints())
			{
				LeftCurbSpline->SetLocationAtSplinePoint(i, NewPosLeft, ESplineCoordinateSpace::Local);
			}
			else
			{
				LeftCurbSpline->AddSplinePoint(NewPosLeft, ESplineCoordinateSpace::Local);
			}

			if (i < RightCurbSpline->GetNumberOfSplinePoints())
			{
				RightCurbSpline->SetLocationAtSplinePoint(i, NewPosRight, ESplineCoordinateSpace::Local);
			}
			else
			{
				RightCurbSpline->AddSplinePoint(NewPosRight, ESplineCoordinateSpace::Local);
			}
		}

		PopulateMeshAlongSpline(LeftCurbSpline, LeftCurbMesh, SplineMeshesLeftCurb);
		PopulateMeshAlongSpline(RightCurbSpline, RightCurbMesh, SplineMeshesRightCurb);

	}
}

.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/SplineComponent.h"
#include "Components/SplineMeshComponent.h"
#include "SplineStreet.generated.h"

UCLASS()
class SOLARDRIVE_API ASplineStreet : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	ASplineStreet();

	UPROPERTY(EditAnywhere)
	UStaticMesh* RoadMesh;

	UPROPERTY(EditAnywhere)
	UStaticMesh* LeftCurbMesh;

	UPROPERTY(EditAnywhere)
	UStaticMesh* RightCurbMesh;

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	virtual void OnConstruction(const FTransform& Transform) override;

	void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangeEvent) override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

private:
	USplineComponent* MainSpline;

	USplineComponent* LeftCurbSpline;
	USplineComponent* RightCurbSpline;

	TArray<USplineMeshComponent*> SplineMeshesLeftCurb;
	TArray<USplineMeshComponent*> SplineMeshesRightCurb;

	ESplineCoordinateSpace::Type SplineLocal = ESplineCoordinateSpace::Local;

	void PopulateMeshAlongSpline(USplineComponent* Spline, UStaticMesh* Mesh, TArray<USplineMeshComponent*> SplineMeshes = {nullptr});
};

This works well for a while after placing the BP in the level, but after some time when i try to edit the Spline Points of the MainSpline, the Engine crashes.
I already updated the drivers. This is driving me crazy as im not sure what is going on here?!
I Would really appriciate some help :slight_smile:

Another minor problem is that the two curb splines path’s aren’t shown in the editor. They flicker for one frame in the BP inspector after clicking on “compile” and then go invisible - but that’s only on the side and not really that important.

The error indicates you are trying to access a memory address of an object / actor that does not exist anymore or is null. Basically you are trying to do something on an object that doesnt appear to exist.

Before using any pointer to an object or actor, try to make sure you always null-check it, anywhere and everywhere.

So in your case, make sure to if(!IsValid(MainSpline)) { return; } and all other pointers at the start of your functions. This way your application wont crash as often, and you will be easily able to spot what behaviour is off so you can fix it.

I figured it would be something like that :confused:
I tried your approach, but that sadly didn’t work: at the start of OnConstruction I added checks for all 3 splines. In the Log I get the Info, that the first curb spline isn’t valid - so nothing gets added/rendered now (previously everything works as intended at least once on initilization).
After re-opening the level and editing the MainSpline, the Engine crashes again with the same Error.

It is always one of these statements that seems to be the culprit (can’t see anything wrong here though):

for (int32 i = 0; i < LeftCurbSpline->GetNumberOfSplinePoints(); i++) {..}

if (i < LeftCurbSpline->GetNumberOfSplinePoints()) {..}

Im trying to Update the project to 5.5.3 tomorrow, maybe that’ll help.

Add UPROPERTY() TO all UObjects

UPROPERTY()
USplineComponent* MainSpline;
UPROPERTY()
	USplineComponent* LeftCurbSpline;
UPROPERTY()
	USplineComponent* RightCurbSpline;
UPROPERTY()
	TArray<USplineMeshComponent*> SplineMeshesLeftCurb;
UPROPERTY()
	TArray<USplineMeshComponent*> SplineMeshesRightCurb;
UPROPERTY()
	ESplineCoordinateSpace::Type SplineLocal = ESplineCoordinateSpace::Local;

otherwise it will be collected and destroyed by the GC

This had no effect. The result is still the same.
Updating the project to 5.5.3 has not changed anything either, except that the engine now crashes on startup even before the spline points are moved.

These lines feel suspect for the two spline components. Why are you setting these in the constructor for those components? This may be causing the object to expect that the construction script will create those objects and prevent them from being copied from the ClassDefaultObject.

1 Like

That fixed it. I copied the code from the MainSpline (which should be editable and only worked properly if this was set) and thought this kind of setup is needed.
Thanks for the help!