Custom destructors -- memory management

Discussion in 'C++' started by Dave Rahardja, Apr 3, 2007.

  1. I need to design a container that must hold a set of references to a variety
    of object types, managed by different memory managers. At some time, the
    container must destroy each object. Currently I have the following design in
    mind:


    class Destructible // interface
    {
    public:
    virtual void destroy() = 0;
    };


    class Container
    {
    public:
    // ...

    void add(Destructible& item);

    // ...
    void destroy();
    };

    void Container::destroy()
    {
    // ... iterate ...
    items.destroy();
    }


    // An item in the container
    class Item: virtual public Destructible
    {
    public:
    virtual void destroy();
    };

    void Item::destroy()
    {
    MyMemoryManager::Lock lock(this);
    ~Item();
    }


    Is there an easier way to do this? Is there a way to make the container work
    with objects without a custom destructor?

    -dr
     
    Dave Rahardja, Apr 3, 2007
    #1
    1. Advertising

  2. On 3 Apr, 07:45, Dave Rahardja
    <> wrote:
    > I need to design a container that must hold a set of references to a variety
    > of object types, managed by different memory managers. At some time, the
    > container must destroy each object. Currently I have the following design in
    > mind:
    >
    > class Destructible // interface
    > {
    > public:
    > virtual void destroy() = 0;
    >
    > };
    >
    > class Container
    > {
    > public:
    > // ...
    >
    > void add(Destructible& item);
    >
    > // ...
    > void destroy();
    >
    > };
    >
    > void Container::destroy()
    > {
    > // ... iterate ...
    > items.destroy();
    >
    > }
    >
    > // An item in the container
    > class Item: virtual public Destructible
    > {
    > public:
    > virtual void destroy();
    >
    > };
    >
    > void Item::destroy()
    > {
    > MyMemoryManager::Lock lock(this);
    > ~Item();
    >
    > }
    >
    > Is there an easier way to do this? Is there a way to make the container work
    > with objects without a custom destructor?


    Maybe I missed some of the requirements but what's wrong with just
    using the normal destructor? If the container uses any of the standard
    containers then the destructor will be called automatically. If you
    are using pointers then the destructor will be called on delete.

    Have you perhaps been using some garbagecollected language like Java
    or C# where you don't know when an object is destroyed? Well, in C++
    you do, so all you have to worry about is to make sure that the object
    is destroyed (going out of scope or using delete on a pointer) and
    that the destructor cleans up the stuff that needs to be cleaned up.

    --
    Erik Wikström
     
    =?iso-8859-1?q?Erik_Wikstr=F6m?=, Apr 3, 2007
    #2
    1. Advertising

  3. Dave Rahardja

    wo Guest

    On Apr 3, 7:45 am, Dave Rahardja
    <> wrote:
    > // ... iterate ...
    > items.destroy();


    Have you ever considered using iterators ? You might want to google
    for "C++ iterator" in order to do such traversal. items is the C
    way of seeing the problem, which isn't really the best one for
    containers where random access (using the [] operator) isn't
    available, like lists.
     
    wo, Apr 3, 2007
    #3
  4. On 2 Apr 2007 23:36:11 -0700, "Erik Wikström" <>
    wrote:

    >On 3 Apr, 07:45, Dave Rahardja
    ><> wrote:
    >> I need to design a container that must hold a set of references to a variety
    >> of object types, managed by different memory managers. At some time, the
    >> container must destroy each object. Currently I have the following design in
    >> mind:

    >
    >Maybe I missed some of the requirements but what's wrong with just
    >using the normal destructor? If the container uses any of the standard
    >containers then the destructor will be called automatically. If you
    >are using pointers then the destructor will be called on delete.
    >
    >Have you perhaps been using some garbagecollected language like Java
    >or C# where you don't know when an object is destroyed? Well, in C++
    >you do, so all you have to worry about is to make sure that the object
    >is destroyed (going out of scope or using delete on a pointer) and
    >that the destructor cleans up the stuff that needs to be cleaned up.


    I'm sorry if I wasn't clear--it wasn't the destructor call that I was worried
    about. It is that each of the elements in this container may be allocated by a
    _different_ memory manager. Thus, using global delete may not be appropriate
    for all elements.

    -dr
     
    Dave Rahardja, Apr 3, 2007
    #4
  5. On 3 Apr 2007 03:55:18 -0700, "wo" <> wrote:

    >On Apr 3, 7:45 am, Dave Rahardja
    ><> wrote:
    >> // ... iterate ...
    >> items.destroy();

    >
    >Have you ever considered using iterators ? You might want to google
    >for "C++ iterator" in order to do such traversal. items is the C
    >way of seeing the problem, which isn't really the best one for
    >containers where random access (using the [] operator) isn't
    >available, like lists.
    >


    Since I am _providing_ the container, I think I should be free to use whatever
    traversal method I like internally! ;-)

    Joking aside, the traversal is not the question here. I merely used the []
    notation to suggest that there is some sort of iteration going on internally
    when the objects are destroyed.

    The question I'm asking is about how to destroy these objects, which may have
    been allocated on a variety of memory managers.

    -dr
     
    Dave Rahardja, Apr 3, 2007
    #5
  6. Dave Rahardja

    James Kanze Guest

    On Apr 3, 3:07 pm, Dave Rahardja
    <> wrote:
    > On 2 Apr 2007 23:36:11 -0700, "Erik Wikström" <>
    > wrote:


    > >On 3 Apr, 07:45, Dave Rahardja
    > ><> wrote:
    > >> I need to design a container that must hold a set of
    > >> references to a variety of object types, managed by
    > >> different memory managers. At some time, the container must
    > >> destroy each object. Currently I have the following design
    > >> in mind:


    > >Maybe I missed some of the requirements but what's wrong with just
    > >using the normal destructor? If the container uses any of the standard
    > >containers then the destructor will be called automatically. If you
    > >are using pointers then the destructor will be called on delete.


    > >Have you perhaps been using some garbagecollected language like Java
    > >or C# where you don't know when an object is destroyed? Well, in C++
    > >you do, so all you have to worry about is to make sure that the object
    > >is destroyed (going out of scope or using delete on a pointer) and
    > >that the destructor cleans up the stuff that needs to be cleaned up.


    > I'm sorry if I wasn't clear--it wasn't the destructor call
    > that I was worried about. It is that each of the elements in
    > this container may be allocated by a _different_ memory
    > manager. Thus, using global delete may not be appropriate for
    > all elements.


    How do you know which memory manager is responsible for a given
    object? If it is purely a function of the type, then using a
    common base class, and providing an operator delete member
    function in the class should do the trick; you just use delete,
    as normal, and the compiler takes care of the rest. Failing
    that, you need some means of tracking which memory manager is
    responsible for which bit of memory. The most frequent solution
    for this is to use some hidden memory in front of the allocated
    block. You then replace the global new and delete functions to
    set this memory, and to use it when they are called. Say
    something along the lines of:

    union BlockHeader
    {
    MemoryManager* owner ;
    double dummyForAlignment ; // may need something more
    // for some processors...
    } ;

    void* operator new( size_t n )
    {
    BlockHeader* result =
    static_cast< BlockHeader * >(
    ::malloc( n + sizeof( BlockHeader ) ) ) ;
    if ( result == NULL ) {
    throw std::bad_alloc() ;
    }
    result->owner = NULL ;
    return result + 1 ;
    }

    void* operator new( size_t n, MemoryManager* from )
    {
    BlockHeader* result =
    static_cast< BlockHeader * >(
    from->alloc( n + sizeof( BlockHeader ) ) ) ;
    if ( result == NULL ) {
    throw std::bad_alloc() ;
    }
    result->owner = from ;
    return result + 1 ;
    }

    void operator delete( void* p )
    {
    BlockHeader* block
    = static_cast< BlockHeader* >( p ) - 1 ;
    if ( block->owner == NULL ) {
    ::free( block ) ;
    } else {
    block->owner->free( block ) ;
    }
    } ;

    Again, this takes care of everything automatically. You
    allocate with new or new(memmgr), and you delete as usual.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Apr 3, 2007
    #6
  7. On 3 Apr 2007 07:50:12 -0700, "James Kanze" <> wrote:

    >How do you know which memory manager is responsible for a given
    >object? If it is purely a function of the type, then using a
    >common base class, and providing an operator delete member
    >function in the class should do the trick; you just use delete,
    >as normal, and the compiler takes care of the rest. Failing
    >that, you need some means of tracking which memory manager is
    >responsible for which bit of memory. The most frequent solution
    >for this is to use some hidden memory in front of the allocated
    >block. You then replace the global new and delete functions to
    >set this memory, and to use it when they are called. Say
    >something along the lines of:


    >
    >Again, this takes care of everything automatically. You
    >allocate with new or new(memmgr), and you delete as usual.


    Hey that's a great idea! That might just be the ticket.

    -dr
     
    Dave Rahardja, Apr 4, 2007
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael Hopkins
    Replies:
    1
    Views:
    360
    Kai-Uwe Bux
    Jun 9, 2006
  2. Michael Hopkins
    Replies:
    1
    Views:
    418
    Tom Widmer
    Jun 9, 2006
  3. someone
    Replies:
    75
    Views:
    1,181
    MikeWhy
    Jan 7, 2012
  4. FtM
    Replies:
    64
    Views:
    1,328
    88888 Dihedral
    Jan 7, 2012
  5. Andrew Torda
    Replies:
    16
    Views:
    182
Loading...

Share This Page