C++ Struct is Having its Data Cleared in Blueprints

USTRUCT(BlueprintType)
struct FMyStruct
{
    GENERATED_BODY()

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    FString String1 = "Default Value";

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    FString String2 = "";

    UPROPERTY(BlueprintReadWrite, EditAnywhere)
    FString String3 = "";
};
UCLASS(BlueprintType, DefaultToInstanced, EditInlineNew)
class UMyObject : public UObject
{
    GENERATED_BODY()

public:
    UFUNCTION(BlueprintCallable, BlueprintPure)
    const FMyStruct& GetStruct()
    {
        // Debugger shows Struct as populated with "Value 1" "Value 2" and "Value 3"
        const MyStruct& Struct = LinkedList->GetCurrent()->GetStruct();

        // Debugger and TempLog show Struct as populated with "Value 1" "Value 2" and "Value 3"
        UE_LOG(/* Outputs Struct.String1, Struct.String2, and Struct.String3 */);

        return Struct; // Blueprint debugger shows "Default Value" "" and ""
    }

private:
    MyLinkedList* LinkedList = nullptr; // Value gets assigned in another function.
};
class MyLinkedList
{
public:
    void Add(FMyStruct& struct);

    Node* GetCurrent() { return Current; }

private:
    Node* Head;
    Node* Current;
};
class Node
{
public:
    Node(const TArray<FMyStruct>& InStructs) : Structs(InStructs) {}

    const MyStruct& GetStruct() const { return Structs[0]; }

private:
    TArray<FMyStruct> Structs;

    Node* Next = nullptr;
};

Node is constructed and added to the Linked List in another class.

By placing breakpoints in GetStruct and on the Blueprint (before, on [when testing without BlueprintPure], and after the GetStruct node), I have confirmed that the node that is returning the default values is the node that is calling the function when the breakpoints show the populated values.

I am aware that passing by const& prevents editing the values. That is the intended design. I’m passing by reference as a performance improvement, and I do not want the values modified.

The struct gets constructed with certain variables and is never, nor should ever be, modified after that. I was originally doing BlueprintReadOnly for the struct variables but changed to BlueprintReadWrite and EditAnywhere for testing.

UPROPERTY(BlueprintReadOnly)
FString String1 = "Default Value";

In Blueprints, I am passing the struct from the getter to a Widget Blueprint.

1 Like