Use TArray in constructor

I’m confused how to use TArray.

It’s three times encounter TArray error.

The first. I use TArray store some template data point to sort. I push data in BeginPlay() function. But after when i used. All point in this container has turn invalid, not nullptr, just some error data or fdfdfd etc. I checked if the template data has been destruct. But all data is fine. I don’t know what happen and no time to spent on it. So i change my way to use the template data’s array index to solve this.

The second. I make a TArray to store some int variable. The requirement is every time when new data list come in, clear old and push all new data into array. Then update by index when used. So i write a function, and put .Empty() function at first. The first set data come from local file. So, i call this function in constructor to load default data. And crash. Like the first one, i can only change way to use std container.

And now. I write a component. I want two element in TArray container when the component add to actor. So, i make this in constructor. and crash again. Them i change is to PostInitProperties function and crash again and again. Just different position in stack.

Some one can tell me how to use TArray in constructor?

the data:

USTRUCT(BlueprintType)
struct FRopeAttachInfo
{
	GENERATED_USTRUCT_BODY()

	/* The rope's particle point index */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Component)
		int32	m_Index;

	/* The socket name on the attach object */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Component)
		FName	m_SocketName;

	/* The attach object data */
	UPROPERTY(EditAnywhere, Category = Component)
		FComponentReference m_AttachObject;

	/* The offset from attach position */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Component, meta = (MakeEditWidget = true))
		FVector m_OffSet;
};

the container:

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Rope")
		TArray<FRopeAttachInfo> m_AttachData;

and the constructor

URopeComponent::URopeComponent(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	PrimaryComponentTick.bCanEverTick = true;
	bTickInEditor = true;
	bAutoActivate = true;

	bAttachStart = true;
	bAttachEnd = true;
	RopeWidth = 10.f;
	m_AttachPointIndex = NumSegments = 10;
	NumSides = 4;
	EndLocation = FVector(100.f, 0, 0);
	RopeLength = 100.f;
	SubstepTime = 0.02f;
	SolverIterations = 1;
	TileMaterial = 1.f;
	CollisionFriction = 0.2f;
	RopeGravityScale = 1.f;

	FRopeAttachInfo tHead;
	tHead.m_Index = 0;
	m_AttachData.Add(tHead);

	FRopeAttachInfo tEnd;
	tEnd.m_Index = NumSegments - 1;
	tEnd.m_OffSet = FVector(100.0f, 0.0f, 0.0f);
	m_AttachData.Add(tEnd);

	SetCollisionProfileName(UCollisionProfile::PhysicsActor_ProfileName);
}

stack:

>	UE4Editor-CoreUObject.dll!TFastReferenceCollector<1,FGCReferenceProcessor<1>,FGCCollector<1>,FGCArrayPool,0>::ProcessObjectArray(FGCArrayStruct & InObjectsToSerializeStruct, const TRefCountPtr<FGraphEvent> & MyCompletionGraphEvent) 行 696	C++
 	UE4Editor-CoreUObject.dll!TFastReferenceCollector<1,FGCReferenceProcessor<1>,FGCCollector<1>,FGCArrayPool,0>::FCollectorTaskQueue::DoTask() 行 381	C++
 	UE4Editor-CoreUObject.dll!TGraphTask<TFastReferenceCollector<1,FGCReferenceProcessor<1>,FGCCollector<1>,FGCArrayPool,0>::FCollectorTaskProcessorTask>::ExecuteTask(TArray<FBaseGraphTask *,FDefaultAllocator> & NewTasks, ENamedThreads::Type CurrentThread) 行 829	C++
 	UE4Editor-Core.dll!FTaskThreadAnyThread::ProcessTasks() 行 934	C++
 	UE4Editor-Core.dll!FTaskThreadAnyThread::ProcessTasksUntilQuit(int QueueIndex) 行 800	C++
 	UE4Editor-Core.dll!FTaskThreadBase::Run() 行 516	C++
 	UE4Editor-Core.dll!FRunnableThreadWin::Run() 行 76	C++
 	UE4Editor-Core.dll!FRunnableThreadWin::GuardedRun() 行 25	C++

Code
link text

Hello,

I noticed that you have defined the constructor for your URopeComponent class, but you have yet to declare it in its header class. Plus its worth noting that it is not necessary to add FObjectInitializer as a parameter for the constructor unless you are editing the UObject defaults for that object.

Thanks,

This code copy from engine’s CableComponent and it can run fine if i block the TArray’s add operation in constructor.

I also notice that when i think the data in container will been destroy by destructor. But it fine. May be some macro has processed it.

You point my want. I just want this component will have tow default data wen it create in editor. And i can change it in detail panel if i want.

This component i write to simulate a rope. So i copy code from Cablecomponent. And change some code to pass compile.

The Cablecomponent have a function can attach start point and end point to a position in default set.

I want my rope can attach any point to any position. So i must change some code to do. That why i add a TArray. But default when i create the rope component, it must fix in some position just like the cable’s default. So i need add two default data in the array container.

Can you point for me how to solve this?

For more, can you explain how the TArray work and why use TArray in constructor so easy to crash for me?

I found there have a logic error that constructor will come in when UE4 launch, and it actually not object in scene. So I change the add operation to OnRegister function. And get the same error and same stack calling.

In order to better understand how TArrays work I would recommend looking at the documentation for TArrays: Array Containers in Unreal Engine | Unreal Engine 5.1 Documentation