CreateDefaultSubobject crashes editor

The following function causes the editor to crash once the compile button is hit:

#define NUM_CHUNKS 26
#define CHUNK_PATH_PFX "/Game/Models/cube-fractured_Cube_cell_"
void ATargetDestructible::LoadChunkedMesh()
{
    FString basePath = TEXT(CHUNK_PATH_PFX);
    for (int x = 0; x < NUM_CHUNKS; x++)
    {
        FString chunkNum = FString::Printf(TEXT("%03d"), x);
        FString chunkPath = basePath + chunkNum;

        UE_LOG(LogTemp, Log, TEXT("%s"), *chunkPath);

        // Start crash inducing code
        UStaticMeshComponent *chunk = NULL;
        chunk = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ChunkMesh"));
        chunk->SetupAttachment(RootComponent);
        // End crash inducing code

        ConstructorHelpers::FObjectFinder<UStaticMesh> asset(*chunkPath);
        if (asset.Succeeded())
            chunk->SetStaticMesh(asset.Object);
    }
}
#undef NUM_CHUNKS
#undef CHUNK_PATH_PFX

Is there a workaround, or am I off the path on how to dynamically load a long list of similar named assets?

Update 1

I’ve managed to slim it down to the following:

void SomeClass::SomeFunction(int *p)
{
    // Ok
    for (int x = 0; x < *p; x++)
    {
        UStaticMeshComponent *chunk = NULL;
        chunk = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ChunkMesh"));
        chunk->SetupAttachment(RootComponent);
    }

    // Ok
    for (int x = 0; x < 1; x++)
    {
        UStaticMeshComponent *chunk = NULL;
        chunk = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ChunkMesh"));
        chunk->SetupAttachment(RootComponent);
    }

    // Crashes
    for (int x = 0; x < 2; x++)
    {
        UStaticMeshComponent *chunk = NULL;
        chunk = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ChunkMesh"));
        chunk->SetupAttachment(RootComponent);
    }
}

The only thing I can think of is that it must be pretty aggressive on loop unrolling and it is breaking somewhere with that? This is only compiling in debug mode, so I wouldn’t think it would get that aggressive?

Update 2

When setting the pointer as volatile, it still produces the crash when more than 1 loop iteration is needed. Side note, why is the compiler ignoring volatile?

void SomeClass::SomeFunction()
{
    int x = 2;
    AnotherFunction(&x);
}

void SomeClass::AnotherFunction(volatile int *p)
{
    for (int x = 0; x < *p; x++)
    {
        UStaticMeshComponent *chunk = NULL;
        chunk = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("ChunkMesh"));
        chunk->SetupAttachment(RootComponent);
    }
}
  1. The unique naming makes sense.
  2. It is inside a constructor

Still curious as to why the compiler ignores volatile.

Two problems I can think of:

  1. You can’t have more than one component with the same name in an actor. You’ll have to do something like appending x to the end of “ChunkMesh” so you have unique names.
  2. CreateDefaultSubobject can’t be run outside of a constructor. If this isn’t running in your constructor you should use NewObject instead, and make sure you also call RegisterComponent when you finish setting up its attachment and and extra processing you need to do.
3 Likes