Download

Editor crashes when trying to set struct equal to struct.

I have been trying to set a struct based on a struct that is passed to it. The struct is the same, but for some reason the engine crashes when I set struct = struct. It only happens to FString and FText from what I can tell.

My struct:


USTRUCT(BlueprintType)
struct FItemData : public FTableRowBase
{
    GENERATED_BODY()

public:
    FItemData()
    : Name("Default")
    , SlotWidth(1)
    , SlotHeight(1)
    , ItemIcon(UTexture2D::CreateTransient(0,0))
    , ItemType(EItemType::DEFAULT)
    , PickupMesh(Cast<UStaticMesh>(UStaticMesh::StaticClass()))
    {}

    UPROPERTY(EditAnywhere, BlueprintReadWrite, category = "ItemData")
    FString Name;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, category = "ItemData")
    int32 SlotWidth;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, category = "ItemData")
    int32 SlotHeight;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, category = "ItemData")
    UTexture2D* ItemIcon;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, category = "ItemData")
    EItemType ItemType;

    UPROPERTY(EditAnywhere, BlueprintReadWrite, category = "ItemData")
    UStaticMesh* PickupMesh;
};

The variable that triggers the crash is “Name”. I have tried it as an FString and an FText.

.h


#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "InteractableBase.h"
#include "InventoryItemBase.generated.h"

/**
 * 
 */
UCLASS()
class INVENTORYTEST_API UInventoryItemBase : public UObject
{
    GENERATED_BODY()

public:
    UInventoryItemBase();

    void SetItemData(FItemData Item);

    void SetInventoryPosition(FVector2D InvPos);
    void SetInventoryPosition(int x, int y);

    FItemData GetItemData() { return ItemData; }

    FVector2D GetInventoryPosition() { return InventoryPosition; }

protected:
    FItemData ItemData;

    FVector2D InventoryPosition;
};

.cpp


#include "InventoryItemBase.h"
#include "InventoryTest/InventoryTestGameMode.h"

#include "Engine/World.h"

UInventoryItemBase::UInventoryItemBase()
{
    InventoryPosition = FVector2D(0.f,0.f);

    ItemData.Name = "Default";
    ItemData.SlotHeight = 1;
    ItemData.SlotWidth = 1;
    ItemData.ItemIcon = UTexture2D::CreateTransient(0, 0);
    ItemData.ItemType = EItemType::DEFAULT;
    ItemData.PickupMesh = Cast<UStaticMesh>(UStaticMesh::StaticClass());
}

void UInventoryItemBase::SetItemData(FItemData Item)
{
    ItemData = Item;
}

In the function SetItemData I tried breaking the struct and setting the members individually using comments to pinpoint how many of them would crash the editor. Only “Name” crashed the editor. And not only is it name it is specifically ItemData.Name that is causing it. I did a UE_Log of ItemData.Name and Item.Name and Item.Name worked.

Additional information:
ItemData on crash. [TABLE]

		Name 			Value 			Type 		


ItemData
{Name=<Error reading characters of string.> SlotWidth=2949172 SlotHeight=6881378 …}
FItemData

		▶ FTableRowBase
		{...}
		FTableRowBase
	


		▶ Name
		&lt;Error reading characters of string.&gt;
		FString
	


		SlotWidth
		2949172
		int
	


		SlotHeight
		6881378
		int
	


		▶ ItemIcon
		0x00430050002f0074 (Name=???)
		UTexture2D *
	


		ItemType
		68 'D'
		EItemType
	


		▶ PickupMesh
		0x00290035004d0053 (Name=???)
		UStaticMesh *

Item on crash [TABLE]

		Name 			Value 			Type 		


Item
{Name=L"Potion" SlotWidth=1 SlotHeight=2 …}
FItemData

		▶ FTableRowBase
		{...}
		FTableRowBase
	


		▶ Name
		L"Potion"
		FString
	


		SlotWidth
		1
		int
	


		SlotHeight
		2
		int
	


		▶ ItemIcon
		0x000001cae2c62800 (Name="nw_it_mpotion_002")
		UTexture2D * {UE4Editor-Engine.dll!UTexture2D}
	


		ItemType
		POTION (4 '\x4')
		EItemType
	


		▶ PickupMesh
		0x000001cad6cd6000 (Name="Shape_NarrowCapsule")
		UStaticMesh * {UE4Editor-Engine.dll!UStaticMesh}

Am I not declaring the struct right in UInventoryItemBase, is this a known problem, or am I missing something?

A number of issues here:



UTexture2D::CreateTransient(0,0)


Don’t do this. Set the texture to nullptr instead. Currently you are allocating a new texture anywhere this struct is created in code. That is a really bad idea. It also makes no sense to create a texture with “zero” size, the engine won’t allow it.



Cast<UStaticMesh>(UStaticMesh::StaticClass());


This makes no sense. You are trying to set a UStaticMesh* pointer to a UClass*. StaticClass() returns a class not an instance of an object. I’m surprised it compiles at all. Again, set it to nullptr.



void SetItemData(FItemData Item);


Everytime you pass this struct to this function, you are copying it. You should be passing by const-ref, like so:



void SetItemData(const FItemData& Item);



As for the error, the data is all invalid because it’s pointing to junk memory. The most likely answer is that the UInventoryItemBase object you are trying to call SetItemData() on is actually nullptr or invalid. The state of memory will not help us diagnose the crash, you should post the output log and/or the callstack.

Thanks for the quick reply. UTexture2D and the Static mesh I had already suspected them of being WAY off when I wrote this. Changing them to nullptr actually fixed the crashing at SetItemData. Now why I didn’t think of just setting them to nullptr to begin with is beyond me. I am going to try and modify the function to pass by const-ref as you suggested.

Again thanks.

EDIT: It fixed the problem for one run. Getting the same error as before.

Just in case someone wanted dig deeper as to why it wasn’t working I am posting the full callstack of the previous error here and attaching the output log (debug)?:

Looks like it’s exactly what I said:



Exception thrown: read access violation.
**this** was 0xFFFFFFFFFFFFFF89.


The object you are calling SetItemData() on is null - so it has likely been garbage collected or never existed. The issue is not with SetItemData, the issue is where you’re trying to call SetItemData