Access violation in packaged game, not in the editor

It happens when I package the project but works fine in the editor. I have a c++ class that extends UGameInstance, it has a TArray with 4 object from my class UOPeerHandler that extends from UObject and inside each they create a ConcretePeer object that doesn’t extend from anything, but receives an string name to start.

I instantiate the TArray inside calling a method “InitialPeerSetup” inside the GameInstance Init Method:

// in UMyGameInstance class

void UMyGameInstance::InitialPeerSetup()
{
	Log("Initial Peer Setup...");
	Peers.Add(NewObject<UOPeerHandler>(this));
	Peers[0]->createClientPeer("DockerPeer", FPeerSettings());
	Log("Peer ready: " + Peers[0]->GetPeerName());
	Peers.Add(NewObject<UOPeerHandler>(this));
	Peers[1]->createClientPeer("StatsPeer", FPeerSettings());
	Log("Peer ready: " + Peers[1]->GetPeerName());
	Peers.Add(NewObject<UOPeerHandler>(this));
	Peers[2]->createClientPeer("DataPeer", FPeerSettings());
	Log("Peer ready: " + Peers[2]->GetPeerName());
	Peers.Add(NewObject<UOPeerHandler>(this));
	Peers[3]->createClientPeer("ChatPeer", FPeerSettings());
	Log("Peer ready: " + Peers[3]->GetPeerName());

}

// in UOPeerHandler class

void UOPeerHandler::createClientPeer(FString name, FPeerSettings settings){
	_clientPeer =  new ConcretePeer(name, settings);
	_clientPeer->SetHandler(*this);
}

I call GetPeerName that ask to the inner object for its string name and it logs the name, but later on, from a blueprint I call a method to get a object by its name:

// in UMyGameInstance class

UOPeerHandler* UMyGameInstance::GetUOPeerHandler(FString PeerName)
{
	Log("asking for peer: "+ PeerName);

	for(auto i = 0; i < 4; i++)
	{
		Log("Verifying peer...");
		if(Peers[i]->GetPeerName() == PeerName)
		{
			return Peers[i];
		}
	}
	Log("Not Found...");
	return nullptr;
}

// in UOPeerHandler class

FString UOPeerHandler::GetPeerName(){
	return _clientPeer->GetPeerName();
}

// in ConcretePeer class

FString ConcretePeer::GetPeerName()
{
#if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT)
	UE_LOG(PhotonNetworking, Warning, TEXT("LOG GAME INSTANCE: should be %s"), *FString(PeerName.c_str())); // FAILS IN PACKAGED GAME NO IN EDITOR
#endif	
	return FString(PeerName.c_str());
}

It fails throwing an Access violation error:

MachineId:00D6DFA244C56598A668EA87D62520F2
EpicAccountId:efecdd0c0449400f8af75aa325cc33f6
Access violation - code c0000005 (first/second chance not available)
(first/second chance not available)
MyProject!ConcretePeer::GetPeerName()
[c:\projectfolder\myproject\myproject.unrealengine\source\myproject\private\network\concretepeer.cpp:155]
MyProject!UOPeerHandler ::GetPeerName()
[c:\projectfolder\myproject\myproject.unrealengine\source\myproject\private\network\uopperhandler.cpp:36]
MyProject!UMyGameInstance ::GetUOPeerHandler()
[c:\projectfolder\myproject\myproject.unrealengine\source\myproject\private\umygameinstance.cpp:60]
MyProject!UMyGameInstance ::execGetUOPeerHandler()
[c:\projectfolder\myproject\myproject.unrealengine\source\myproject\public\umygameinstance.h:15]

Its like PeerName doesn’t exist anymore…

Hello Lunatic_Lucian,

Is it possible that this function is being called before what is being passed into this function is initialized? I would suggest trying to preface this GetPeerName function call with an if to check if PeerName is valid. It’s possible that this was already initialized in the editor so when hitting play it wasn’t a problem but with the packaged game, nothing has been initialized when it starts. It’s the only thing I can immediately think of.

Hi Matthew,

this is the packaged game log and as you can see I logged the initial setup call and check that the GetPeerName function work… but then later it fails… so its called and the objects are instantiated. I’ll attach the log filelink text

(sorry, new on this, I’ve posted the log in another comment)

Can you try running the game in a Standalone Window from the editor to see if the behavior is the same? If so, try connecting the Visual Studio debugger to it. This should allow you to look at the values and see exactly what is going wrong.

Ok I did that and when the Peers are set, for example the first peer “DockerPeer”, the debugger says for Peers[0]:

UObject : (Name: 0x000000000003113548 “UOPeerHandler”_0)
_clientPeer: 0x000000000e28cda0 { IsConnected: false PeerName: “DockerPeer”…}

But then when try to run method GetUOPeerHandler Peer[0] says:

UObject : (Name: 0x00000000000960010 “None”_0)
_clientPeer: 0x000000000fffffff { IsConnected: ??? PeerName: {…} …}

And When I expand the PeerName it says:

[size] :
[capacity] :
[allocator] : allocator
[Dimensions] :
[] :

Also peer in Peers[3] says:

UObject : (Invalid)
_clientPeer: 0x000000000fffffff { IsConnected: ??? PeerName: {…} …}

No clue why this happen.

Ok I found the solution. Thanks Matthew for helping me with the dubug option.

Th think is that to avoid an uobject class to turn an invalid object, after reading this article , for each of the UOPeerHandler instances I needed to call:

Peers[0]->AddToRoot();

In order to prevent them to be garbage collected. And since they should exist all the game lifetime I dont needed to handle their deallocation.