Getting access violation code c0000005 in editor, but not standalone game

Whenever I launch my game in the selected viewport, Unreal crashes and presents that error code. However, when I launch the game as a standalone, it works fine.

The full log is:
Access violation - code c0000005 (first/second chance not available)

UE4Editor_UQuake!AUQuakeCharacter::GetCurrentWeaponAmmo() [f:\my documents\repos\uquake\source\uquake\uquakecharacter.cpp:197]
UE4Editor_UQuake!AUQuakeHUD::DrawHUD() [f:\my documents\repos\uquake\source\uquake\uquakehud.cpp:41]
UE4Editor_Engine!AHUD::PostRender() [d:\build\++ue4+release-4.14+compile\sync\engine\source\runtime\engine\private\hud.cpp:158]
UE4Editor_Engine!UGameViewportClient::Draw() [d:\build\++ue4+release-4.14+compile\sync\engine\source\runtime\engine\private\gameviewportclient.cpp:1213]
UE4Editor_Engine!FViewport::Draw() [d:\build\++ue4+release-4.14+compile\sync\engine\source\runtime\engine\private\unrealclient.cpp:1163]
UE4Editor_UnrealEd!UEditorEngine::Tick() [d:\build\++ue4+release-4.14+compile\sync\engine\source\editor\unrealed\private\editorengine.cpp:1615]
UE4Editor_UnrealEd!UUnrealEdEngine::Tick() [d:\build\++ue4+release-4.14+compile\sync\engine\source\editor\unrealed\private\unrealedengine.cpp:371]
UE4Editor!FEngineLoop::Tick() [d:\build\++ue4+release-4.14+compile\sync\engine\source\runtime\launch\private\launchengineloop.cpp:2859]
UE4Editor!GuardedMain() [d:\build\++ue4+release-4.14+compile\sync\engine\source\runtime\launch\private\launch.cpp:152]
UE4Editor!GuardedMainWrapper() [d:\build\++ue4+release-4.14+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:126]
UE4Editor!WinMain() [d:\build\++ue4+release-4.14+compile\sync\engine\source\runtime\launch\private\windows\launchwindows.cpp:202]
UE4Editor!__scrt_common_main_seh() [f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl:264]
kernel32
ntdll

However, GetCurrentWeaponAmmo() is a single line statement, which does appear to work. In both cases, the HUD does draw the correct value for the weapon ammo, so I’m not sure why it’s only crashing in the editor window.

EDIT: Ok, it turns out that I accidentally had left Unreal launching 2 players instead of 1. Putting it back to 1 prevented the crash in the editor window. So the question becomes why does it crash on 2 players?

Looks like a null pointer (or accessing a GC’d object). What does your DrawHUD method look like? Is it using a weak obj ptr to store the AUQuakeCharacter and checking that its valid before accessing it?

It’s just stored as class AUQuakeCharacter* Player, and I’m not checking for validity. I’ll wrap it in a null-check and see if it works with 2 players.

Ok, I wrapped up the code in if (Player && Player->IsValidLowLevel()), but it still causes a crash when doing multiplayer.

I’m not sure just checking a raw pointer will work.

Try this:

TWeakObjPtr<AUQuakeCharacter> Player;

if (Player.isValid())
{
  Player->GetCurrentWeaponAmmo();
}

Nope, that still causes a crash in multiplayer. Maybe it’s how I’m getting the reference to the player in the HUD class? In BeginPlay, I’m doing:

Player = Cast<AUQuakeCharacter>(UGameplayStatics::GetPlayerPawn(this, 0));

If Player is a TWeakObjPtr, I would expect even if UGameplayStatics::GetPlayerPawn returned a nullptr - you would be safe from the crash. I would toss a break point in there and see what GetPlayerPawn is returning.

Looks like the problem is that the CurrentWeapon on the second player becomes null after a few frames. I’m not sure why that’s happening, unless it’s because I’m handling weapon switching entirely on the server.

That would make sense if you are destroying the weapon on the server when you do a switch.

Again, this is where a TWeakObjPtr is awesome as you can just toss in something like this:

if (Player.IsValid() && Player->GetCurrentWeapon().IsValid())
{
   Player->GetCurrentWeaponAmmo();
}

Unfortunately, the weapon is simply detached from the player and hidden, not destroyed, so I’m not sure why the pointer is becoming null.

Are you setting it as replicated? If not it won’t get sent to other clients.

Aha, that’s the problem! Thanks! Found a few other bugs as a result, but that should also be solved by setting them to replicate.

For posterity:

The problem here was the object wasn’t set to Replicate(via UPROPERTY and DOREPLIFETIME), so when executed in Multiplayer the object didn’t exist on a client that isn’t also the server.

Also, Smart pointers(TWeakPtr, TWeakObjPtr) are your friend to help avoid nullptr pointer crashes. :slight_smile: