Access violation - code c0000005...is anything wrong with my getter function?

Hi there,

today I discovered a problem with my code which ends in this crash log

Access violation - code c0000005 (first/second chance not available)
UE4Editor_ShadowOverMykthynaar!ABaseItem::GetItemIcon() + 0 bytes [c:\users\documents\unreal projects\shadowovermykthynaar\source\shadowovermykthynaar\private\item\baseitem.cpp:106]
UE4Editor_ShadowOverMykthynaar!ASoMHUD::DrawInventory() + 2337 bytes [c:\users\documents\unreal projects\shadowovermykthynaar\source\shadowovermykthynaar\private\somhud.cpp:429]
UE4Editor_ShadowOverMykthynaar!ASoMHUD::DrawHUD() + 117 bytes [c:\users\documents\unreal projects\shadowovermykthynaar\source\shadowovermykthynaar\private\somhud.cpp:118]
UE4Editor_Engine!AHUD::PostRender() + 337 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\engine\private\hud.cpp:139]
UE4Editor_Engine!UGameViewportClient::Draw() + 6930 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\engine\private\gameviewportclient.cpp:1069]
UE4Editor_Engine!FViewport::Draw() + 1223 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\engine\private\unrealclient.cpp:995]
UE4Editor_UnrealEd!UEditorEngine::Tick() + 8339 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\editor\unrealed\private\editor.cpp:1515]
UE4Editor_UnrealEd!UUnrealEdEngine::Tick() + 22 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\editor\unrealed\private\unrealedengine.cpp:347]
UE4Editor!FEngineLoop::Tick() + 4179 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\launch\private\launchengineloop.cpp:2257]
UE4Editor!GuardedMain() + 1404 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\launch\private\launch.cpp:142]
UE4Editor!GuardedMainWrapper() + 26 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\launch\private\windows\launchwindows.cpp:126]
UE4Editor!WinMain() + 249 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.7\engine\source\runtime\launch\private\windows\launchwindows.cpp:202]
UE4Editor!__tmainCRTStartup() + 329 bytes [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c:618]

It happens when the inventoy is open an at least one item is stored…in this case it will load the icon (from various Item BP) and display it in the inventory. The crash don’t happen instantly as soon as the inventory is open. At first everything is fine, but if I wait between 20 - 60 seconds with an open inventory window I could wait for the crash.

The called function in the BaseItem class is:

UTexture2D* ABaseItem::GetItemIcon() const
{
	return ItemIcon;
}

it returns Texture2D* ItemIcon and is called by this function from my HUD Class which draws the inventory:

DrawScaledTile(TempItem[iItem]->GetItemIcon(), xPosInventory, yPosInventory, InventorySlotWidth, InventorySlotHeight, FColor(255, 255, 255, 255));

Do you have any ideas (from looking at the crash log) how I can avoid the crash? At the moment I don’t see exactly why it happens. I see that GetItemIcon() has 0 bytes in the log, but why?

Try to validate ItemIcon before returning it.

Cancel:

The Arrayindex is always taken from this loop the call is located in

for(int32 iItem = 0; iItem < Pawn->GetPlayerInventory().Num(); iItem++)

it should be always valid since it is always the current size of the stored items.

Martin Egger:

Sorry for the stupid question, but how should I validate this value (Texture2D)?

If tried this before

if(ItemIcon)
{
return ItemIcon;
}
else
return ErrorIcon;

I returned an ErrorIcon in case if ItemIcon don’t exist, but it also crashed with the same message.
Is there a better way to validate the Texture2D-Pointer (I’m sure it is)

Thanks to you both for your answers

Thanks,

I actually created the array in the function as temporary array with out UPROPERTY(). I fixed it, but if didn’t fix the crashes, unfortunally.

Here is how I coded it:

Header:

/** An array to store the items of the player inventory */
	UPROPERTY()
	TArray<ABaseItem*> TempItem;

/** A pointer to the player class */
UPROPERTY()
APlayerCharacter* Pawn;

CPP:

/** Draw Inventory */
//
void ASoMHUD::DrawInventory()
{
	// Reset the Array to update the Inventory
	TempItem.Reset();

	// Set xPos/ yPos
	xPosInventory = GetScreenDimensions().X - ((InventorySlotWidth + DefaultSlotDistance) * InventoryDefaultColumns + ScreenBorderPaddingX);
	yPosInventory = GetScreenDimensions().Y / 6;

	// Get a reference to the player
	Pawn = Cast<APlayerCharacter>(GetOwningPawn());

	if (Pawn && Pawn->GetPlayerInventory().Num() >= 1)
	{
		// Assigning the PlayerInventoryArray to the TempItemArray
		TempItem = Pawn->GetPlayerInventory();

		// Draw the inventory based on the items stored in the PlayerInventory Array
		for (int32 iItem = 0; iItem < TempItem.Num(); iItem++)
		{

			
			// Draw the Button
			DrawScaledTile(ButtonInventorySlotDefault, xPosInventory, yPosInventory, InventorySlotWidth, InventorySlotHeight, FColor(255, 255, 255, 255));
			// Draw the icon of the inventory item
			DrawScaledTile(TempItem[iItem]->GetItemIcon(), xPosInventory, yPosInventory, InventorySlotWidth, InventorySlotHeight, FColor(255, 255, 255, 255));
		}
	}
}

This is all were TempItem is involved and can mess up the iterator

Thanks Cancel,

that fixed the problem…in the meantime I also figured out how the issue popped up.

Yesterday I changed a function in the BaseItem class to destroy the whole object once the item was picked up and added to the inventory. So the actual BP Object was not in the scene anymore. It seemed much cleaner to me than just destroying it’s mesh and triggercomponent. Obviously a pretty stupid idea.

But this brings up the question how to handle the whole item system. Our game is Open World RPG, The World is big but not huge. If if every item needs actually be in the scene once a plant or chest or something was looted to be displayed in the inventory, I need to spawn them all at a location in the scene until there are actually consumed, sold or destroyed. Am I right?

It just seems like a giant mess to me…I think at least I’ll destroy or disable their visual components, collider and triggers to not waste performance