I’m trying to build an inventory class that holds references to items, but whenever I try to add an item reference to the TArray the game crashes. Do I need to initialize my array somehow? Relevant code is below. Please let me know what I’m doing wrong, and the correct way to approach this.
// Item is clicked on in game
void ATDSItem::ItemOnClicked(UPrimitiveComponent* ClickedComponent)
// Get reference to local character
ATDSCharacter* myChar = Cast<ATDSCharacter>(GetWorld()->GetFirstPlayerController()->GetCharacter());
// Pickup this item
// Pick up the item that was clicked on to player inventory
void ATDSCharacter::PickupItem(ATDSItem* Item)
bool bAdded = PlayerInventory->AddItem(Item);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, (FString("Picked up item: ") + Item->Name));
UPROPERTY(EditAnywhere, Category = Inventory)
TArray<class ATDSItem*> Items;
// Add the item to inventory
bool ATDSInventory::AddItem(ATDSItem* Item)
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, (FString(Item->Name)));
Items.Add(Item); // Crashes here with an access violation
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, (FString("Item null")));
On crashes it is useful to include a callstack.
Is the PlayerInventory variable in ATDSCharacter::PickupItem NULL or an invalid pointer?
Quite hard to tell anything not seeing ATDSItem properties. Build in debug and trace what leads to crash.
It’s not null, as it crashes inside PlayerInventory->AddItem(Item); call at the line 32.
I’ve experienced some problems with TArray in the past as well, some of the properties were making troubles somehow… not sure how i fixed that. But it surely hard to debug in development build.
Non-virtual function calls don’t actually use the object pointer at the time of the function call (X->Foo()), they use it the first time a member variable accessed. Without seeing the header it’s difficult to tell, but if ATDSInventory::AddItem is non-virtual then the first time it actually accesses a member variable (and would crash from a NULL this pointer) is when it accesses the ITems array.
Here is a simple C++ test application that demonstrates this
Hm, i see. Didn’t actually know that, shame on me. Thank you for clarifications.
Yes. In the debug trace “this” the PlayerInventory is null. So in my Character class I have ATDSInventory* PlayerInventory; which I’m looking at now and realizing how not-smart that was because I actually wanted a new instance there. The thing is, I only added that * because it wont let me compile ATDSInventory PlayerInventory;
Is there some other syntax for creating an instance of an AActor class?
UObjects can’t be created on the frame, they must always be constructed on the heap via special functions UE4 provides.
I am assuming ATDSInventory is an Actor, based on its naming. Actors have a special construction path, here is an answer which demonstrates how to spawn an actor.
You have to spawn your PlayerInventory before accessing its members. Probably in BeginPlay of your character do something like this:
PlayerInventory = GetWorld()->SpawnActor<ATDSInventory>(ATDSInventory::StaticClass());
That did the trick!
Well, for some reason there’s nothing to mark as an answer on the page, but thanks so much for helping me out. You guys are both awesome. Props to both of you.
Thanks to BiggestSmile and solid_angle for helping me debug.
I had not correctly created an instance of my PlayerInventory actor causing the reference from my .h file to be null:
PlayerInventory = GetWorld()->SpawnActor(ATDSInventory::StaticClass());