Access violation when exiting the player

The Exception

I am currently creating a game that uses a Third Party library that I made to handle some calculations. The game launches correctly and I can play in it no problem but when I exit the player (or a standalone player) I get this exception:

Message

33808-message.png

Output

Here is the output:

The thread 0x4a64 has exited with code 0 (0x0).
The thread 0x4a60 has exited with code 0 (0x0).
First-chance exception at 0x000007FEEC50F3A9 (UE4Editor-CoreUObject.dll) in UE4Editor.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
Unhandled exception at 0x000007FEEC50F3A9 (UE4Editor-CoreUObject.dll) in UE4Editor.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.

Stack

And here is the stack:

UE4Editor-CoreUObject.dll!IncrementalPurgeGarbage(bool bUseTimeLimit, float TimeLimit) Line 982	C++
UE4Editor-CoreUObject.dll!CollectGarbage(EObjectFlags KeepFlags, bool bPerformFullPurge) Line 1169	C++
UE4Editor-UnrealEd.dll!UEditorEngine::EndPlayMap() Line 236	C++
UE4Editor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 966	C++
UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 347	C++
UE4Editor.exe!FEngineLoop::Tick() Line 2257	C++
UE4Editor.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 142	C++
UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 191	C++
[External Code]	

Code

My code consists of two classes:

GameMapModel.h

UCLASS()
class SLTTEST2_API AGameMapModel : public AActor, public IMapModelController
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AGameMapModel();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;
};

The class IMapModelController belongs to my Third Party library, GameMapModel doesn’t do anything but initialize a class in IMapModelController. Apart from that one function is called during gameplay:

IMapModelController.cpp

bool framework::IMapModelController::assignModelToController(Controller* controller)
{
	if (controller != nullptr)
	{
		controller->setModel(mapModel);
	}

	else
	{
		throw std::invalid_argument("The controller pointer sent to assignModelToController in MapModelController has not been initialized");
	}
}

This Actor is placed as is in the Map.

GameSensorPresence.h

This is my second class, a blueprint is created with it as a parent and it interacts with the GameMapModel and some of the elements in the ThirdPartyLibrary.

UCLASS(Blueprintable)
class SLTTEST2_API AGameSensorPresence : public AActor, public ISensorPresenceController, public IObserver, public enable_shared_from_this<AGameSensorPresence>
{
	GENERATED_BODY()
	
public:	
	UPROPERTY(BlueprintReadOnly, Category = "Sensor State")
		bool on;

	UPROPERTY(BlueprintReadOnly, Category = "Sensor State")
		bool triggered;

	UPROPERTY(BlueprintReadOnly, Category = "Sensor State")
		bool ledOn;

	UPROPERTY(BlueprintReadOnly, Category = "Sensor State")
		float energyConsumption;

	//UPROPERTY(BlueprintReadWrite, Category = "Sensor State")
	ProtocolType protocol;

	// Sets default values for this actor's properties
	AGameSensorPresence();

	// Called when the game starts or when spawned
	virtual void BeginPlay() override;
	
	// Called every frame
	virtual void Tick( float DeltaSeconds ) override;

	UFUNCTION(BlueprintCallable, Category = "Sensor State")
		bool onDiscoveryTriggered() override;

	UFUNCTION(BlueprintCallable, Category = "Sensor State")
		bool onPresenceDetected(bool isPresence) override;

	UFUNCTION(BlueprintCallable, Category = "Sensor State")
		void onSensorOnOff(bool isOn) override;

	UFUNCTION(BlueprintCallable, Category = "Sensor State")
		void getSensorState();

	UFUNCTION(BlueprintNativeEvent, Category = "Sensor State")
		void Update() override;

	UFUNCTION(BlueprintCallable, Category = "Sensor Creation")
		void setProtocolType(uint8 type);
};

GameSensorPresence.cpp

I assume most of this functions should not cause any problems because I get the exception even when they are not triggered during game-play. The ones that are triggered are these:

AGameSensorPresence::AGameSensorPresence()
{
	// 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;

	this->on = true;
	this->triggered = false;
	this->energyConsumption = 0;
	this->ledOn = false;
	this->protocol = ProtocolType::DUMMY;
}

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

	UWorld* world = this->GetWorld();
	for (TActorIterator<AGameMapModel> It(world); It; ++It)
	{
		It->assignModelToController(this);
	}

	onSensorCreate(this, protocol);
}

Please Help!

There is all the information I think might help figure out where does this exception come from. If you need anything else just ask.

Please help!! I really need to get this working!! Thank you in advance!

Can you post your IMapModelController.h?

The only things I am seeing without knowing more about the third party library are bad/lingering references to “mapModel”, whatever mapModel is.

Are you initializing this with null/good values?

Have you tried cleaning up “mapModel” on EndPlay or DestroyActor?

Sorry, you’re right, I meant BeginDestroy.

Looking at the callstack, its definitely having issue removing a UObject of some kind. The address its spewing is indicative of something that was deleted already and is being deleted again or something that never really had a good value to begin with.

Its a late night and I might be missing something, but I don’t see anything else that stands out and would have to assume its something to do with this third party library.

Are you destroying any UObjects yourself?

Perhaps put in more checks in places to make sure the UObjects you are dealing with are valid?

Make sure all UObject pointers are initialized to null?

Lastly, when you use functions like EndPlay and BeginDestroy, make sure you call their parent implementations if you are overriding. This is very important. Bad things can happen otherwise.

I could not find the function DestroyActor, only K2_DestroyActor(), ReceiveDestroyed(), BeginDestroy() and Destroyed().

I did not try them. I did try cleaning up on EndPlay:

void AGameMapModel::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
	IMapModelController::~IMapModelController();
}

But the exception persisted.

Should I try any of these Destroy functions?

IMapModelController.h

Here is the header you requested:-

class IMapModelController
{
public:
	~IMapModelController();
	virtual bool assignModelToController(Controller* controller);
	virtual bool saveModel();
	virtual bool loadModel(string path);
protected:
	IMapModelController(shared_ptr<IDeviceFactory> factory);
private:
	shared_ptr<MapModel> mapModel;
};

Hum I tried to use BeginDestroy instead of EndPlay but the results were the same. Thanks for the tip about calling their parent implementations. (And for your help overall)

I have no references to UObjects in my code on the Engine side, on the other hand if you look at GameSensorPresence it inherits form one of my ThirdParty classes IObserver.

Inside the ThirdParty library there is this that might be related to the error:
(Sorry I cannot copy all the code here)

class Foo() : public Subject
{
private:
	shared_ptr<IObserver> observer;
public:
	void attach(shared_ptr<IObserver> observer) override;
	void dettach(shared_ptr<IObserver> observer) override;
	void notify() override;
};

Basically Foo() attaches an IObserver which is the GameSensorPresence, (an UObject).
When Foo is deleted this happens:

Foo::~Foo()
{
	observer.reset();
}

Could this be the cause?

Foo is deleted when MapModel destroyer is called (when IMapModelController is destroyed) If I got my pointer ownership right.

(I will try to prevent it from deleting its pointers to IObserver)

Now I get the exception when running the game ò.ó

Stack

 	KernelBase.dll!000007fefe3a3ca2()	Unknown
>	UE4Editor-Engine.dll!FTickFunction::QueueTickFunction(const FTickContext & TickContext) Line 1049	C++
 	UE4Editor-Engine.dll!FTickTaskLevel::QueueAllTicks() Line 367	C++
 	UE4Editor-Engine.dll!FTickTaskManager::StartFrame(UWorld * InWorld, float InDeltaSeconds, ELevelTick InTickType) Line 620	C++
 	UE4Editor-Engine.dll!UWorld::Tick(ELevelTick TickType, float DeltaSeconds) Line 1112	C++
 	UE4Editor-UnrealEd.dll!UEditorEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 1329	C++
 	UE4Editor-UnrealEd.dll!UUnrealEdEngine::Tick(float DeltaSeconds, bool bIdleMode) Line 347	C++
 	UE4Editor.exe!FEngineLoop::Tick() Line 2257	C++
 	UE4Editor.exe!GuardedMain(const wchar_t * CmdLine, HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, int nCmdShow) Line 142	C++
 	UE4Editor.exe!WinMain(HINSTANCE__ * hInInstance, HINSTANCE__ * hPrevInstance, char * __formal, int nCmdShow) Line 191	C++
 	[External Code]	

I only changed from this in Foo:

class Foo() : public Subject
 {
 private:
     shared_ptr<IObserver> observer;
 public:
     void attach(shared_ptr<IObserver> observer) override;
     void dettach(shared_ptr<IObserver> observer) override;
     void notify() override;
 };

To this:

class Foo() : public Subject
{
private:
IObserver* observer;
public:
void attach(IObserver* observer) override;
void dettach(IObserver* observer) override;
void notify() override;
};

Foo::~Foo()
{
    observer = nullptr;
}

I do not understand at all what is happening anymore…

Ok solved, for whomever might read this:

I changed Foo from this:

class Foo() : public Subject
 {
 private:
     shared_ptr<IObserver> observer;
 public:
     void attach(shared_ptr<IObserver> observer) override;
     void dettach(shared_ptr<IObserver> observer) override;
     void notify() override;
 };

To this:

class Foo() : public Subject
 {
 private:
     IObserver* observer;
 public:
     void attach(IObserver* observer) override;
     void dettach(IObserver* observer) override;
     void notify() override;
 };

And made this in the destroyer:

Foo::~Foo()
{
    observer = null
}

This prevents my class from destroying an UObject and allows the Game Engine to clean up its own mess ;D

Thanks @Allar for your suggestions and explanations, I wouldn’t have gotten here if it wasn’t for this phrase in particular:

Looking at the callstack, its
definitely having issue removing a
UObject of some kind. The address its
spewing is indicative of something
that was deleted already and is being
deleted again or something that never
really had a good value to begin with.

I hope this helps someone else with a similar problem!