Issue with UObject memory access violation

Hey guys, I’m running into an issue and was hoping to get some help from more experienced programmers. I’m attempting to instantiate a UObject I have created for a player that contains data for their hand, field and deck.

When the constructor runs, everything seems just fine and I’m able to access and use this player object, but thereafter the object seems to get lost, maybe due to GC? In a test function, the player object causes a memory access violation, code below. Any help or ideas would be much appreciated, thanks!

#include "GameTest.h"
#include "CardData.h"

AGameTest::AGameTest()
{
    Player = NewObject<UCardPlayer>();
    PrimaryActorTick.bCanEverTick = false;
    for(int i = 0; i < 10; i++)
    {
        Player->Deck.push_back(Cards[0]);
        Player->Deck.push_back(Cards[1]);
    }

    Player->DrawCard(5);

    if(GEngine)
        GEngine->AddOnScreenDebugMessage(-10, 1.f, FColor::Yellow, FString::Printf(TEXT("%llu"), Player->Hand.size()));
}

int AGameTest::TestFunction()
{
    if(GEngine)
    {
        GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("Function called in game"));
        // This causes a crash due to memory access violation. 
        return Player->Hand.size();
    }

    return 0;
}

void AGameTest::BeginPlay()
{
    Super::BeginPlay();
}

Maybe. How is the Player variable declared?
The variable must be marked as:

UPROPERTY()

Additionally, Epic recommends against using regular pointers (at least in variables inside UObject).
In your case it will work:

TObjectPtr<UCardPlayer>

You can find out more about other types of pointers this or this.

1 Like

@SupTwo

This is a common mistake: you misunderstood what the constructor does in Unreal Engine, it’s not the same as regular C++ constructor.

See documentation about UObject Creation - “UObjects should only be constructed using NewObject at runtime, or CreateDefaultSubobject for constructors.” - In your code you’re using NewObject inside of AGameTest::AGameTest constructor which is against said rule.

I presume, you wanted to fire some logic when the AGameTest actor spawns (when the Game starts). In this case you should probably move everything from AGameTest::AGameTest to AGameTest::BeginPlay.

This code is simply not going to work the way you expect. Read about Unreal Engine Reflection System and especially about CDO (Class Default Object).
Also, this one might be useful: c++ - Unreal Engine 4. Different ways to instantiate the object - Stack Overflow

1 Like

Ah, this was the issue, yes! Thanks for sharing all the links as well.

1 Like