How to prevent destructors from calling objects managed by boost :: fast_pool_allocator?

I would like to take advantage of the following feature advertised boost::fast_pool_allocator(see the Boost documentation for the Boost Pool ):

For example, you may have a situation where you want to select a bunch of small objects at one point, and then reach a point in yours where none of them are needed anymore. Using the pool interfaces, you can choose to run your destructors or simply remove them into oblivion ...

(see here for this quote.)

The key phrase throws them into oblivion . I do not want destructors to call these objects.

(The reason is that I have millions of tiny objects that make up the extremely complex ownership network on the heap, and it takes about 20 minutes for my program to call all destructors when an object with one parent object goes off the stack. I don't need these destructors because there are no desired side effects and all memory is contained in boost::pool.)

Unfortunately, despite the promise of the above documentation and the promise of the concept boost::pool, I cannot find a way to prevent managed object destructors from being called.

The task is easily isolated in a small sample program:

class Obj
{
public:
    ~Obj()
    {
        // Placing a breakpoint here indicates that this is *always* reached
        // (except for the crash scenario discussed below)
        int m = 0;
    }
};

typedef std::map<int, Obj, std::less<int>,
                 boost::fast_pool_allocator<std::pair<int const, Obj>>>
        fast_int_to_int_map;

class Foo
{
public:
    ~Foo()
    {
        // When the following line is uncommented, the program CRASHES
        // when the destructor is exited - because the Obj destructors
        // are called on the invalid Obj ghost instances

        //boost::singleton_pool<boost::fast_pool_allocator_tag,
        //                  sizeof(std::pair<int const, Obj>)>::purge_memory();
    }

    fast_int_to_int_map mmap;
};

void mfoo()
{
    // When this function exits, the Foo instance goes off the stack
    // and its destructor is called, in turn calling the destructors
    // of the Obj instances - this is NOT desired!

    Foo foo;
    foo.mmap[0] = Obj();
    foo.mmap[1] = Obj();
}

int main()
{
    mfoo();

    // The following line deallocates the memory of the pool just fine -
    // but does nothing to prevent the destructors of the Obj instances
    // from being called

    boost::singleton_pool<boost::fast_pool_allocator_tag,
                          sizeof(std::pair<int const, Obj>)>::purge_memory();
}

As noted in the code comments, instance destructors Objthat are managed boost::poolare always invoked.

, Boost Pool, drop them off into oblivion, ?

+4
3

std::map. , std::map: Obj , std::map. , purge_memory() Foo destructor, , std::map .

, , : std::map . , ~Obj() , .

. :

  • placement new Foo ,
  • Foo ,
  • purge_memory(), . ~Obj ~std::map .
+3

default_user_allocator_new_delete. , , . default_user_allocator_malloc_free malloc' - drop[ing] them off into oblivion.

, , , - , .

+1

@qehgt .

:

:

  • (1)

  • (2)

- (1).

(2), , , , , . / , .

, : - new delete ( , , , , , purge_memory()):

class Obj { // has operator<() for use with std::set };

typedef std::set<Obj, std::less<Obj>, boost::fast_pool_allocator<Obj>> fast_set_obj;

// Deliberately do not use a managed pointer -
// I will *NOT* delete this object, but instead
// I will manage the memory using the memory pool!!!
fast_set_obj * mset = new fast_set_obj;

// ... add some Obj to 'mset'
mset->insert(Obj());
mset->insert(Obj());

// Do something desireable with the set ...
...

// All done.
// It time to release the memory, but do NOT call any Obj destructors.
// The following line of code works exactly as intended.

boost::singleton_pool<boost::fast_pool_allocator_tag, sizeof(Obj const)>::purge_memory();

( ).

, : , set map. . .

0

Source: https://habr.com/ru/post/1535590/


All Articles