Why does IsValid Crash?

I made an editor widget utility. Within that utility in my header file I defined the private variable
TMap<FString, AActor*> ActorNameCache;

In my code I have the following:
AActor* Obj = FindActorByName(Box->Name);
if (Obj == nullptr || !IsValid(Obj))

It all works fine, except after I have loaded the cache, if I then delete an object in the editor then the line:
if (Obj == nullptr || !IsValid(Obj))
is crashing with the error
Unknown() Address = 0x180ecb684 (filename not found) [in libsystem_platform.dylib]

Here is my find actor function:

AActor* UEditorTools::FindActorByName(const FString& Name)
{
FString ModifiedName = Name;
ModifiedName.ReplaceInline(TEXT(“/”), TEXT(““));
ModifiedName.ReplaceInline(TEXT(”.“), TEXT(”
”));
ModifiedName = ModifiedName.TrimEnd();

// Check the cache first

if (AActor** CachedActor = ActorNameCache.Find(ModifiedName))
{
    if (CachedActor && *CachedActor && IsValid(*CachedActor) && IsActorInWorld(*CachedActor)) // Added IsActorInWorld check
    {
        return *CachedActor;
    }
    else{
        return nullptr;
    }
}

// Get the current world context
UWorld* World = GetWorld();
if (!World)
{
    return nullptr; // Ensure the world is valid
}

// Iterate over all actors in the world
for (TActorIterator<AActor> It(World); It; ++It)
{
    AActor* Actor = *It;
    if (Actor && Actor->ActorHasTag(FName(*ModifiedName))) // Converts FString to FName correctly
    {
        ActorNameCache.Add(ModifiedName, Actor); // Cache the result
        return Actor; // Return the found actor
    }
}

// If no actor found, cache the result as nullptr to avoid repeated searches
ActorNameCache.Add(ModifiedName, nullptr);
return nullptr; // No matching actor found

}

Maybe do a nullptr check on CachedActor before you try double de-referencing it?

(Can you even double de-reference in this case? Your TMap value is a single pointer. Once you pass in the string for find you already should have access to the actor’s pointer.)

You could also check if the key even exists in the map after that step.

if(ActorNameCache.Contains(Box->Name)){
}

Also do you do a nullptr check on Box anywhere?
I’m guessing you are getting a crash in the compound if statement.
Try splitting them up into separate tests with a break point and see where chaos ensues.

Is ActorNameCache a property? If it isn’t, then actors can be deleted and they won’t be set to null.

Also, you should use TObjectPtr instead of raw pointers.

You are the best! TObjectPtr seemed to resolve the issue (additionally, I made ActorNameCache a property, but I believe I had tried that before and it hadn’t worked).

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.