Struct types in constructors cause editor crash

Create a struct such as:

USTRUCT(BlueprintType)
struct FPlayerInfo
{
    UPROPERTY(...)
    int HitPoints;

   UPROPERTY(...)
   int MaxHitPoints;
}

My game instance has a map of strings to the info

TMap<FString,FPlayerInfo> _playerInfoMap;

In the constructor to the game instance

UMyInstance::UMyInstance(FObjectInitializer const & init)
	: Super(init)
{
	UE_LOG(MyLog, Log, TEXT("Init stats"));
	FPlayerInfo aliceStats;
	aliceStats.HitPoints = aliceStats.MaxHitPoints = 50;
	_stats[TEXT("Alice")] = aliceStats;

	FPlayerInfo brandonStats;
	brandonStats.HitPoints = brandonStats.MaxHitPoints = 60;
	_stats[TEXT("Brandon")] = brandonStats;
}

This causes an editor crash on compile. The project cannot be reloaded after the crash as it will subsequently fail on the splash screen.

Hi Sean

Please find the log attached.

MachineId:

Cheers!

link text

Hello,

  • Could you please provide the logs from your project’s Saved->Logs folder after you cause the crash to occur again?
  • Can you please cause the crash and provide the Machine ID from the Crash Reporter window and ensure to hit send on the report?

I see a few unique crashes under this ID. Could you please provide the callstack of the crash you are seeing that is related to this post so that I can identify which one we should be focused on?

OK will try to sort that out… In the meantime, more info. The problem is caused not by the USTRUCT itself, but by the TMap. The assignment

TMap<FString,FInfo> map;
FInfo info;
map[TEXT("me")] = info;

will cause the crash. However the use of map.Add( TEXT(“me”), info ) will work. This suggests to me that the operator of the TMap for lvalues has not been implemented correctly (hence the assertion failure in the crash log).

Assertion failed: Pair != nullptr [File:C:\Program Files (x86)\Epic Games\4.11\Engine\Source\Runtime\Core\Public\Containers\Map.h] [Line: 520]

The code for the lvalue operator[] reads

	FORCEINLINE ValueType& FindChecked(KeyConstPointerType Key)
	{
		auto* Pair = Pairs.Find(Key);
		check( Pair != nullptr );
		return Pair->Value;
	}

however the lvalue variant only should maybe read (pseudocode)

auto * Pair = Pairs.Find(Key);
if (Pair == nullptr)
{
    Pair = create_pair( Key, Value );
    Pairs.Add( Pair );
}
return Pair->Value;

This ensures that map[x] = y doesn’t assert if there is no x in the map. Assertions should not really be taking down the entire editor, really - loss of project data is a serious downer.

Were you able to determine the callstack of the crash that you were getting so that I can look it up in our database?

Hi Sean, no that kinda got lost in the mix as I had a whole bunch of crash reports. Please refer to the reply I made 4 days ago, the bug is in the lvalue variant of the operator of the TMap class. I should be able to say

map["x"] = 10;

even if there is no existing “x” entry. However the operator calls FindItem() which returns nullptr if the entry is not present, and then asserts. Note that

auto y = map["x"]

can justifiably assert, so the code is goo for the rvalue version of the operator.

Hello,

It looks like you’re using regular array notation. What you need to do is use map.Add instead. This issue is probably related to UHT or UBT looking for formatting, and since you’ve discovered that using map.Add works properly, then continue to use that in the future to avoid running into this issue.

Have a great day