Download

Simple std::unique_ptr issue

Hi,

I have a tiny piece of code which is throwing a lot of errors relating to accessing a deleted function, which I read is because of trying to give more than one owner to a unique_ptr, which is not allowed. However, I’m not aware how this code is doing that, so that reasoning doesn’t make sense to me. Then again, I’m new to pointers in general and very new to smart pointers.


TArray<std::unique_ptr<UInventoryItem>> items;

My UInventoryItem class is very simple; it’s completely empty and just inherits from UObject publicly.

Why could this be, and how can I change the code to fix it? I’d like to stay away from raw pointers entirely unless I have no other choice.

You shouldn’t be using std::unique_ptr with UObjects as those objects are managed by the engine and will be garbage collected. Your issue is unique_ptr is also trying to manage that memory.

Your code should be:



UPROPERTY()
TArray<UInventoryItem*> Items;


By making your Item Array a UPROPERTY, you are holding on to a reference to those objects contained within the array (so GC won’t touch it yet). When you want to delete the object, you can just remove it from the array and then engine will take care of destroying it.

Ok excellent, thank you! I’ve learned a few things there. Does this mean that regardless what I do, all UObject pointers will always be cleaned up automatically by the Engine once they go out of scope?

At Gameplay Level, Unreal uses a garbage collector. Indeed, you don’t have to worry about deleting anything. As soon as the object’s reference count hits 0, the object will be marked for deletion and the garbage collector will take care of it. Now, this only works in objects that derive from UObject and the reference count will only go up for references that are marked as UPROPERTY(). So make sure to mark every pointer as UPROPERTY() as otherwise the garbage collector might end up deleting an object when you are still using it and thus cause a crash.

Now you can use smart pointers within Unreal but not the std ones. The engine has wrappers for each type of smart pointer that you can look into. Some can be used with UObject classes and some are meant for other classes.

Unreal has its own Smart Pointer Library.
https://docs.unrealengine.com/en-US/…PointerLibrary

However you should never use smart pointer on UObjects, since they are memory managed by the engine through its GC.
For the same reason, you should never use the keyword “new” when you try to create an UObject instance, use the NewObject<T> function instead.

Also do not use the std library. UE4 C++ API has everything you could need, seriously.

I suggest you to read some UE4 C++ tutorial, since UE4 C++ is kinda different than “vanilla” C++.

This is common for new devs starting with Unreal.
It’s important to avoid tho… Where I work if you use std:: namespace in Unreal code you’re going to get fired on the spot :expressionless:

This problem is not specific to std:: types; array elements without copy constructors could be supported as long as certain operations are avoided. Is there an explicit policy that TArray not support array elements without a copy constructor? (If so, it is not documented.)
I still think TArray<std::unique_ptr<SomeType>> should compile and not complain about the missing copy constructor of std::unique_ptr.
Finally, I would like to note that there are certain cases, such as interfacing with third-party libraries, where it makes sense to mix std:: and unreal types, and that this support is important although most teams would not normally allow this in regular game code.