FVector values change drastically in function

Hi!

I’ve been writing a volume for my game which is supposed to spawn rocks that are falling on player.
I’ve set up a FTimerDelegate that is bound with spawn function and timer that executes a given delegate after every 3 seconds.

void AStoneEmitterVolume::BeginPlay()
{
	Super::BeginPlay();

	FVector VolumeLocation = VolumeComponent->GetComponentLocation();
	UE_LOG(LogTemp, Warning, TEXT("VolumeLocation: %s"), *VolumeLocation.ToString());


	FTimerHandle SpawnTimerHandle;
	FTimerDelegate EmitStoneDelegate;
	EmitStoneDelegate.BindUFunction(this, FName{ TEXT("SpawnStones") }, &VolumeLocation);
	GetWorldTimerManager().SetTimer(SpawnTimerHandle, EmitStoneDelegate, SpawnDelay, true);
}

The line
“UE_LOG(LogTemp, Warning, TEXT(“VolumeLocation: %s”), *VolumeLocation.ToString());”
inputs the exact location of BoxComponent. But wait for it - things will get interesting soon.

void AStoneEmitterVolume::SpawnStones(FVector& Location)
{
	if (SpawnableActor)
	{
		FVector* SpawnLocation = &Location;
		UE_LOG(LogTemp, Warning, TEXT("VolumeLocation: %s"), *SpawnLocation->ToString());
		UE_LOG(LogTemp, Warning, TEXT("VolumeComponent->GetComponentLocation(): %s"), *VolumeComponent->GetComponentLocation().ToString());

		FActorSpawnParameters SpawnInfo;
		ABreakableObstacle* SpawnedActor = Cast<ABreakableObstacle>(()->SpawnActor(ABreakableObstacle::StaticClass(), SpawnLocation, &FRotator::ZeroRotator, SpawnInfo));
		SpawnedActor->GetRenderComponent()->SetMobility(EComponentMobility::Movable);
		SpawnedActor->GetRenderComponent()->SetSimulatePhysics(true);
		SpawnedActor->GetRenderComponent()->SetConstraintMode(EDOFMode::XZPlane);
		UE_LOG(LogTemp, Warning, TEXT("SpawnedActor exists: %s"), (SpawnedActor) ? TEXT("TRUE") : TEXT("FALSE"));

	}
}

So I log the value of the volumecomponent location as vector refence on the line

UE_LOG(LogTemp, Warning, TEXT(“VolumeLocation: %s”), *SpawnLocation->ToString());

and it outputs me a value VolumeLocation: X=4663971676160.000 Y=0.000 Z=-431595552.000

However, when I log the volumecomponent location directly on the line

UE_LOG(LogTemp, Warning, TEXT(“VolumeComponent->GetComponentLocation(): %s”), *VolumeComponent->GetComponentLocation().ToString());

I get the right vector value.

I am not sure what’s causing this weird behavior, I’ve also tried to find answers on the internet, but haven’t found any similar problem yet.

Waiting for your response,
With regards

That because you passing to SpawnStones function a vector pointer to local varable of other function. If you don’t know pointer (varable type with * in you case FVector*, note that references FVector& are also work like pointers) contains memory address to real varable and you can read it from pointer. Local varable depending on how compiler compiles the code is either stored in RAM (which also may be CPU Cache) or CPU register (if compiler optimize it that way).

Once function containing local variable is done the local varable is either deallocated or replaced with something else. If it get deallocated you will get crash trying to access it or like in your case if it’s not deallocated you will get a trash data as point where that varable was stored is now used by something else and you reading that data, that data don’t need to be float data that why you get those crazy values.

In other words you accessing so called invalid pointer, most dangerus thing in C/C++ because you can’t verify if set pointer points to something existent. As all your code is turned in to CPU machine code and all variables are turn in to nameless memory addresses, your program or OS can’t determent if pointer is valid or else you track that information, that why you should always null pointers when object storing the pointing variables is destroyed (For example UE4 tracks existence status of all UObjects and all UPROPERTYs referencing to it get nulled, it also possible to use check validity using IsValidLowLevel() function in any UObject). But what you doing is not even unsafe (as it can can crash) it won’t work at all because reasons mentioned above.

You should make private varable inside AStoneEmitterVolume that will hold that VolumeLocation so it will be persistent and exist as long as actor exists.

Design wise, i assume you want SpawnStones to be callable elsewhere thats why you use FVector argument insted of reading vector direcly form component. In such case normaly you should use function overload, one with FVector argument and one without any argument that will read VolumeComponent->GetComponentLocation() and execute SpawnStones(FVector& Location). But function overloads are not supported by reflection system, you can’t have 2 UFUNCTIONs with same name (thats why it rare to find function overloads in UE4 APIs), so alternatively you can make 2 functions with different names if both need to be UFUNCTIONs, effect will be the same. This will allow you to avoid using pointers at all.

Hey!

Thanks alot for so detailed answer.

As you suggested, I made the VolumeLocation variable of type FVector private field:

private:
	FVector VolumeLocation;

and initalized it in BeginPlay() function (also tried constructor to set the default value for it), but still when I log the value of this private field, it keeps outputting me values like

X=-0.000 Y=0.000 Z=-431595552.000

X=157570240.000 Y=0.000 Z=-431595552.000




About the goal of this function (why I’ve added FVector reference as it’s input) is because I want to change the value of VolumeLocation variable in Tick function over time using box extent and world location information to randomize the location where stones should fall.

You not declering local varable anymore right? maybe try public? maybe timer code passing pointer as normal FVector over reference, so maybe try FVector* argument. There still definitely some type casting or memory addressing issue.

The error truly is weird. But you’re right - it has to do something with memory addresses…

When I tried to add FVector pointer type argument as function input, I’d run into issue as I’m trying to access the address of FVector type variable (VolumeComponent->GetComponentLocation() returns FVector).

When I created a function SpawnStones(FVector Location) and added directly a FVector type of value into the function it worked, but now it seems I firstly have two variable addresses instead of one - class field and then the function variable’s address.

Do you have any suggestions how can I log variable addresses?