Download

tarray with pointer crashing engine

I’m trying to create an array of pointers to character objects. I assume tarrays will resize automatically according to what I’ve read when putting things in them. As soon as I place an new object in the array and try to access one of its variables to set, it crashes. How can I make an array of pointers locally in a function and set a member array of pointers equal to the local array. I have tried adding the UPROPERTY on top of the local array and member array.



//TArray<FString> data is passed in

TArray<ACustomer*> customers;

for (int i = 0; i < data.Num(); i++)
{
      ACustomer* customer = (ACustomer*)GetWorld()->SpawnActor(ACustomer::StaticClass());
      UE_LOG(LogTemp, Log, TEXT("add new customer %d"), j);
      customers.Add(customer);

      customers[j]->SetName(data*);
      customers[j]->SetMoney(FCString::Atoi(*data*));
      j++;
}

mRecurringCustomers = customers;


So the SetName(data*) line is confirmed to be causing the crash? Does using the SetName and SetMoney on the ‘customer’ variable also cause it to crash?

If it’s crashing because customers[j] is null, but ‘customer’ is non-null, then I would check to make sure ‘j’ is the correct index.

It’s likely your indices are just mismatched somehow (I’m not sure how you are setting “J”, etc). You can avoid using “J” altogether if you simply call your methods before adding the pointer to your array - you can also get rid of the extra array, it’s not needed.



for (int i = 0; i < data.Num(); i++)
{
      ACustomer* customer = (ACustomer*)GetWorld()->SpawnActor(ACustomer::StaticClass());
      UE_LOG(LogTemp, Log, TEXT("add new customer %d"), j);

      customer->SetName(data*);
      customer->SetMoney(FCString::Atoi(*data*));
      
      mRecurringCustomers.Add(customer);
} 

Also, if you want to be super safe, rather than storing an array of “ACustomer*”, change your array to be “TArray<TWeakObjPtr>” - that will wrap your raw pointers in a weak pointer. You use them the exact same way as a naked pointer, but you can also call “IsValid” to verify they haven’t been cleaned up out from under you.



TArray<TWeakObjPtr<ACustomer>> mRecurringCustomers;

//...

int someIndex = 0;
if (mRecurringCustomers[someIndex].IsValid() ) // Is our Pointer still valid?
{
    mRecurringCustomers[someIndex]->DoStuff();
}
else // Pointer is bad, remove it.
{
  mRecurringCustomers.RemoveAt(someIndex);
}