How to check a pointer valid?

i have a pointer ACharacter* in my code, every tick call ACharacter’s function for my logic, in other game logic, it may destroyed, is there any good way to check the pointer is valid? i try call “->IsValidLowLevel()”, but some time it crash in it. which way is suggest?

Generally speaking, there are two options here:

// Works with arbitrary pointers
if(pointer != nullptr) { ... } 
// Only works with objects that inherit from UObject
if(IsValid(pointer)) { ... }

Option 1 is the normal C++ way. It has a couple of limitations you need to be aware of when working with Unreal.

  1. You absolutely need to initialize your pointers manually
  2. Just because a pointer isn’t NULL, doesn’t mean you can use it safely

The first one is something even experienced C and C++ programmers trip over occasionally.

UObject *obj;
// Do stuff, but don't change obj
if (obj != nullptr)    // Almost certain (although not guaranteed) to be true, even if obj isn't valid
{
    obj->...    // Almost certain to crash
}

The problem is the first line, which should read UObject *obj = nullptr; instead. Variables aren’t magic. They’re nothing more than a bit of memory you’ve given a name. The line UObject *obj; does nothing to said memory, so the value of obj is whatever random bits and bytes just happened to be in your memory at the time it was called. The chances of the memory there being NULL are extraordinarily low.

The second problem is that Unreal uses a very complex memory management system and UObject derived classes (which also includes AActor and therefore your character) take part in it. If you put an UE_LOG(…) into both the constructor and EndPlay() functions of your character, you will notice that Unreal instantiates and destroys those actors multiple times in PIE.
Your pointer may point to an actual character with valid data, but using it may still be unsafe because it has been marked for destruction. That’s why you should use IsValid(pointer) instead, because it will also return false, if the pointer points to an object, but the object should not be used anymore.

4 Likes

thank you!
my ACharacter* is create from blueprint, and code logic need to call some function of it, so my code contain a pointer of it, only a c++ pointer and not with UPROPERTY. nullptr is checked when i use it, pointer not nullptr but the obj may not valid(i guess it was be destroyed), so it crash when i call it. how to check a pointer of object is safe to use?

if(IsValid(pointer))

You should use a TWeakObjectPtr<ACharacter> to hold the weak character reference in your code.

Is it specifically designed for this sort of thing:

/***
 * 
 * FWeakObjectPtr is a weak pointer to a UObject. 
 * It can return nullptr later if the object is garbage collected.
 * It has no impact on if the object is garbage collected or not.
 * It can't be directly used across a network.
 *
 * Most often it is used when you explicitly do NOT want to prevent something from being garbage collected.
 **/

thank you !!!
i know TWeakObjectPtr can do this, is there any way to check a c++ pointer valid in ue4 api? or for check it, must use TWeakObjectPtr? :slight_smile:

for example, can i use Obj->IsValidLowLevel() Obj->IsPendingKill() Obj->IsUnreachable() to check it ?

Yes, you can check if a “normal” C++ pointer is valid with if(IsValid(pointer)).

I recently found a different way that I like a little better as it will actually log an error instead of silently failing. You can use ensure. If ensure fails it will log a long error in the log but your game will not crash. It will also tell you exactly which ensure failed and the line number so you know instantly which pointer is causing the problem making debugging much easier.

if (ensure(ObjectPointer))
{
    // do stuff here as ObjectPointer is ok to use
}

https://forums.unrealengine.com/development-discussion/c-gameplay-programming/1530131-ensure-not-working-after-first-run-of-compilation