SOLVED Removing an object from a PointerArray without deleting it

Hi,

short question, for some reason I can't figure this out...

I have a maxon::PointerArray<MyClass>, and I need to remove one of the elements, but without freeing the pointed object (instead, I'll add it to another PointerArray later). I believe, PointerArray::ErasePtr() is the correct function for this, but I can't get rid of the compile errors.

maxon::PointerArray<MyClass> array;

// Array is filled with objects
// This is done as described in the SDK docs:
MyClass* newObjPtr = NewObj(MyClass) iferr_return;
maxon::UniqueRef<MyClass> newObjRef = newObjPtr;
array.AppendPtr(newObjRef) iferr_return;
newObjRef.Disconnect();

// Remove an element from the array, so the array gives up the ownership, but the object still exists
// This obviously not working.
MyClass* formerElemPtr = nullptr;
array.ErasePtr(index, *formerElemPtr) iferr_return;

All I want is the element to vanish from the array, but I still need a valid pointer to it. What's the correct way to do this?

Thanks in advance.

Cheers,
Frank

Hello @fwilleke80,

Thank you for reaching out to us. We will discuss your question tomorrow and Maxime or Manuel might know more, but for me it looks pretty much like what you want to do, releasing an object from the ownership of the PointerArray, is not possible. It is in my understanding the whole purpose of the type to take ownership of its pointed objects. As the manual of the type also states:

In general, it is recommended to manage the lifetime of an object using references, see References.

So, have you considered using references, e.g., StrongRef, StrongCOWRef, or WeakRef? You could also implement MyClass as a (maxon) interface which will give you implicit memory management.

It is here at least for me hard to say what would be the best route for you, as I do not fully understand yet what you are doing and why you get your compilation errors. But when you want to have two arrays A and B which both point to a shared pool of objects, you could make A a BaseArray of StrongRef to these objects (assuming you do not need copy on write), and B a BaseArray of WeakRef to these objects. When you remove objects from A, they will be reference garbage collected and the pointer in B would become invalid. You could technically do the same just with plain pointers, it is just that our API handles the deallocation of things for you.

But I have still the feeling that I do not understand something here, and it might be helpful for us for tomorrow if you would line out what you are trying to achieve.

Cheers,
Ferdinand

Hi Ferdinand,

thanks for your reply!

I am managing multiply PointerArrays, each for a different purpose, and I need to move their elements from one PointerArray to another. Since the objects the array elements point to are rather complex, I want to avoid copying them when moving them to another array.

PointerArray::ErasePtr() sounds like it does exactly what I want. The documentation says:

*ResultPtr<T> ErasePtr(Int position, T** dst)
Extracts a single element from the list and returns its pointer.
The caller takes ownership of the element.

I just can't figure out how to call it correctly, so I'll have the pointer removed from the array, and I end up with a pointer to the removed element of which I now have the ownership.

Cheers,
Frank

Hey @fwilleke80,

Thank you for the update. I looked into our code base and found an example for the method, the code is pretty straight forward, so I am not sure if this will help you:

maxon::PointerArray<iColorSwatchGroup> managedPointers;
maxon::BaseArray<iColorSwatchGroup*> otherData; // Could also be another collection type
Int index;

iColorSwatchGroup* moveGroup = nullptr;
managedPointers.ErasePtr(index, &moveGroup) iferr_return;
otherData.Append(moveGroup) iferr_return;

I currently do not have the time to write a custom example and test out all the ins and outs myself. I will have time around Wednesday next week again, please let me know when you still need assistance.

Cheers,
Ferdinand

Hi Ferdinand,

thank you! In deed, that looks pretty simple. Wonder why I couldn't get it to compile...

I'll test this and report back in case it doesn't work. Since I guess you found it in active code, I'll mark this thread as solved for now. thanks again!

Cheers,
Frank