Tool for object Lifetime = unique_ptr; Tool for Memory Lifetime = ?

Started by
3 comments, last by hyyou 6 years, 10 months ago

As I know, tools for managing object lifetime are :-

  • std::unique_ptr
  • std::move
  • move constructor
  • move assignment
  • delete copy constructor
  • delete copy assigment

With those tools, it is very obvious to determine owner of any certain object - the owner is the one who stores std::unique_ptr as a field.

However, it is obscure which class actually controls memory allocation.

There are only few tools to help :-

  • the second template parameter of std::unique_ptr
  • the second template parameter of std::vector and other datastructure

None of them indicate which instance of allocator is the ownership of such address.

In a scope of class, it is alarming that underlying memory of a std::unique_ptr (that a class owns) can be deallocated any times. (e.g. from pop operation of scope allocators).


std::unique_ptr<SomeThing> a=scopeAllocator->makeUnique<SomeThing>();
scopeAllocator->pop();
//memory of "a" is invalid!

Are there any tools/techniques to help/prevent it, or at least make thing more obvious for coder?

Advertisement
These tools are designed to work best when the object lifetime and allocation lifetime match exactly.

If the object was allocated from a scope allocator, then the scope allocator itself IS the owner. It's not a good idea to use a unique_ptr as well...
These tools are designed to work best when the object lifetime and allocation lifetime match exactly.

Thank a lot Hodgman! It sounds very nice.

How to make an allocator own the objects?

  • Should I cache them by void* and cache the correct deleter (function pointer) for each one?
  • If I understand correctly, any one-frame allocator should also return weak pointer. (?)

i.e. are there any good practice to follow?

What if the return result is a bit obscure?


template<class T>class CustomVector{
     T* t;//
};
class AISystem{
    public: static CustomVector<NPC_ID> reportAllNearNPC(){
        //use "scopeAllocator" to allocate "CustomVector::t"
    }
};
CustomVector<NPC_ID> a=aiSystem->reportAllNearNPC();
scopeAllocator->pop();
//"a.t" become dangling pointer

Your comment is very valuable - it is better than the chapter "allocator" in every C++ books I have read, thank!

I desire to know more. If it is not too much to ask, may you recommend name of some good books :D please?

When you allocate objects (not PODs) from a scope allocator, then the scope allocator is supposed to call destructors (and release memory). That's the entire reason for using it over a simpler linear allocator. Does it even make sense to wrap objects in unique_ptr then? You'd call destructors twice, and in the strictest sense you are telling lies because now two owners own the object although you say only one does (and only one should). That's really bad.

On the other hand, the calling of destructors and (conceptual) release of memory usually happens at the end of a scope, not when you manually call a pop() function (why would I even want to pop the allocator at an inopportune time?). End of scope may of course mean "end of frame" or "end of level", and it may "manually" call a pop function. But that point in time is exactly well-defined, it's not happening randomly when the objects are still being accessed afterwards. Which means it basically does the same thing unique_ptr would do as well, at the same time, only for a whole bunch of objects.
the strictest sense you are telling lies

It is totally reasonable and also enlightens me, thank!

What if the result value has some pointer inside?

For example, it is a data-structure that may or may not the owner of the underlying data, should I create 2 classes like this? :-


//old version
template<class T>class CustomArray{ //type of return result
    unique_pointer<void*> database; //underlying data
};

//new version
template<class T>class WeakArray{
    T* database;
};
template<class T>class StrongArray{
    unique_pointer_toArray<Bullet*> database;//just example
};
//inside a function of some system
WeakArray<Bullet> arr;
arr.t = scopeAllocator->makeWeakArray<Bullet>(5);//similar as new Bullet[5];
return arr;

This topic is closed to new replies.

Advertisement