Overloaded delete does not calls the destructor??

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • rohits123@gmail.com

    Overloaded delete does not calls the destructor??

    I have an overload delete operator as below

    //////////////////////////////////
    void operator delete(void* mem,int head_type) {
    mmHead local_Head = CPRMemory::GetM emoryHead(head_ type);
    mmFree(&local_H ead,(char *)mem);
    CPRMemory::SetM emoryHeadAs(loc al_Head,head_ty pe);
    }
    /////////////////////
    void* operator new(size_t sz, int head_Type) {
    char *mem;
    mmHead local_Head = CPRMemory::GetM emoryHead(head_ Type);
    mem = mmAlloc(&local_ Head,sz);
    CPRMemory::SetM emoryHeadAs(loc al_Head,head_Ty pe);
    if(!mem) cout<<"Out of Memory"<<endl;
    return mem;
    }
    ////////////////
    and using it as

    SmC* s1 = new(WORK_HEAD) SmC;
    operator delete (s1,WORK_HEAD) ;

    But the problem is overloaded delete operator is not calling the
    destructor of class SmC.
    Do I have to call the destructor explicitly?
    Any suggestions please.

  • Dave Rahardja

    #2
    Re: Overloaded delete does not calls the destructor??

    On 6 Feb 2007 18:11:37 -0800, rohits123@gmail .com wrote:
    >I have an overload delete operator as below
    >
    >//////////////////////////////////
    >void operator delete(void* mem,int head_type) {
    > mmHead local_Head = CPRMemory::GetM emoryHead(head_ type);
    > mmFree(&local_H ead,(char *)mem);
    > CPRMemory::SetM emoryHeadAs(loc al_Head,head_ty pe);
    >}
    >/////////////////////
    >void* operator new(size_t sz, int head_Type) {
    > char *mem;
    > mmHead local_Head = CPRMemory::GetM emoryHead(head_ Type);
    > mem = mmAlloc(&local_ Head,sz);
    > CPRMemory::SetM emoryHeadAs(loc al_Head,head_Ty pe);
    > if(!mem) cout<<"Out of Memory"<<endl;
    > return mem;
    >}
    >////////////////
    >and using it as
    >
    SmC* s1 = new(WORK_HEAD) SmC;
    >operator delete (s1,WORK_HEAD) ;
    >
    >But the problem is overloaded delete operator is not calling the
    >destructor of class SmC.
    >Do I have to call the destructor explicitly?
    >Any suggestions please.
    You've overridden placement delete, which is used only to deallocate memory in
    case a constructor throws an exception. The destructor is not called if you
    call placement delete.

    What you need to do is to override placement new, placement delete, _and_
    normal delete:


    // Placement new
    void* operator new(size_t sz, int) { /* ... */ }

    // Placement delete
    void operator delete(void*, int) { /* ... */ } // Note: no size_t parameter!

    // Normal delete
    void operator delete(void*) { /* ... */ }

    then

    SmC* s1 = new(WORK_HEAD) SmC; // Calls placement new
    delete s1; // Calls normal delete, destructor called first.


    If the constructor for SmC throws an exception, the placement delete function
    will be called.

    -dr

    Comment

    • Dave Rahardja

      #3
      Re: Overloaded delete does not calls the destructor??

      On 6 Feb 2007 18:11:37 -0800, rohits123@gmail .com wrote:
      >I have an overload delete operator as below
      >
      >//////////////////////////////////
      >void operator delete(void* mem,int head_type) {
      > mmHead local_Head = CPRMemory::GetM emoryHead(head_ type);
      > mmFree(&local_H ead,(char *)mem);
      > CPRMemory::SetM emoryHeadAs(loc al_Head,head_ty pe);
      >}
      >/////////////////////
      >void* operator new(size_t sz, int head_Type) {
      > char *mem;
      > mmHead local_Head = CPRMemory::GetM emoryHead(head_ Type);
      > mem = mmAlloc(&local_ Head,sz);
      > CPRMemory::SetM emoryHeadAs(loc al_Head,head_Ty pe);
      > if(!mem) cout<<"Out of Memory"<<endl;
      > return mem;
      >}
      >////////////////
      >and using it as
      >
      SmC* s1 = new(WORK_HEAD) SmC;
      >operator delete (s1,WORK_HEAD) ;
      >
      >But the problem is overloaded delete operator is not calling the
      >destructor of class SmC.
      >Do I have to call the destructor explicitly?
      >Any suggestions please.
      By the way, you should follow convention when overriding operator new:



      void* operator new(size_t, int)
      {
      while (true)
      {
      if ( /* allocation successful? */ )
      {
      return /* ptr to memory */
      }

      std::new_handle r handler = std::set_new_ha ndler(0);
      std::set_new_ha ndler(handler);

      if (handler)
      {
      (*handler)();
      }
      else
      {
      throw std::bad_alloc( );
      }
      }
      }

      Comment

      • rohits123@gmail.com

        #4
        Re: Overloaded delete does not calls the destructor??

        On Feb 7, 3:46 pm, Dave Rahardja <a...@me.comwro te:
        On 6 Feb 2007 18:11:37 -0800, rohits...@gmail .com wrote:
        >
        >
        >
        I have an overload delete operator as below
        >
        //////////////////////////////////
        void operator delete(void* mem,int head_type) {
        mmHead local_Head = CPRMemory::GetM emoryHead(head_ type);
        mmFree(&local_H ead,(char *)mem);
        CPRMemory::SetM emoryHeadAs(loc al_Head,head_ty pe);
        }
        /////////////////////
        void* operator new(size_t sz, int head_Type) {
        char *mem;
        mmHead local_Head = CPRMemory::GetM emoryHead(head_ Type);
        mem = mmAlloc(&local_ Head,sz);
        CPRMemory::SetM emoryHeadAs(loc al_Head,head_Ty pe);
        if(!mem) cout<<"Out of Memory"<<endl;
        return mem;
        }
        ////////////////
        and using it as
        >
        SmC* s1 = new(WORK_HEAD) SmC;
        operator delete (s1,WORK_HEAD) ;
        >
        But the problem is overloaded delete operator is not calling the
        destructor of class SmC.
        Do I have to call the destructor explicitly?
        Any suggestions please.
        >
        You've overridden placement delete, which is used only to deallocate memory in
        case a constructor throws an exception. The destructor is not called if you
        call placement delete.
        >
        What you need to do is to override placement new, placement delete, _and_
        normal delete:
        >
        // Placement new
        void* operator new(size_t sz, int) { /* ... */ }
        >
        // Placement delete
        void operator delete(void*, int) { /* ... */ } // Note: no size_t parameter!
        >
        // Normal delete
        void operator delete(void*) { /* ... */ }
        >
        then
        >
        SmC* s1 = new(WORK_HEAD) SmC; // Calls placement new
        delete s1; // Calls normal delete, destructor called first.
        >
        If the constructor for SmC throws an exception, the placement delete function
        will be called.
        >
        -dr
        HI Dave ,

        I am trying for memory optimization .
        I have a chunk of memory which will be divided in to smaller pools of
        memory .
        So, my overloaded new will allocate memory from a particular pool.
        Now during delete I need to know from which pool I need to free the
        memory.
        Due to this I need to use placement delete so that I can pass the pool
        related info to the
        overloaded delete. But I want to delete to call destructor also.

        Allocation and freeing here means getting the memory from a linked
        list of free nodes and adding it to linked list of allocated
        node .Deleting means adding the node back to the link list.
        These two lists are maintained inside a pool.

        Comment

        • =?iso-8859-1?q?Erik_Wikstr=F6m?=

          #5
          Re: Overloaded delete does not calls the destructor??

          On Feb 7, 8:13 am, rohits...@gmail .com wrote:
          On Feb 7, 3:46 pm, Dave Rahardja <a...@me.comwro te:
          >
          >
          >
          On 6 Feb 2007 18:11:37 -0800, rohits...@gmail .com wrote:
          >
          >I have an overload delete operator as below
          >
          >//////////////////////////////////
          >void operator delete(void* mem,int head_type) {
          mmHead local_Head = CPRMemory::GetM emoryHead(head_ type);
          mmFree(&local_H ead,(char *)mem);
          CPRMemory::SetM emoryHeadAs(loc al_Head,head_ty pe);
          >}
          >/////////////////////
          >void* operator new(size_t sz, int head_Type) {
          char *mem;
          mmHead local_Head = CPRMemory::GetM emoryHead(head_ Type);
          mem = mmAlloc(&local_ Head,sz);
          CPRMemory::SetM emoryHeadAs(loc al_Head,head_Ty pe);
          if(!mem) cout<<"Out of Memory"<<endl;
          return mem;
          >}
          >////////////////
          >and using it as
          >
          SmC* s1 = new(WORK_HEAD) SmC;
          >operator delete (s1,WORK_HEAD) ;
          >
          >But the problem is overloaded delete operator is not calling the
          >destructor of class SmC.
          >Do I have to call the destructor explicitly?
          >Any suggestions please.
          >
          You've overridden placement delete, which is used only to deallocate memory in
          case a constructor throws an exception. The destructor is not called ifyou
          call placement delete.
          >
          What you need to do is to override placement new, placement delete, _and_
          normal delete:
          >
          // Placement new
          void* operator new(size_t sz, int) { /* ... */ }
          >
          // Placement delete
          void operator delete(void*, int) { /* ... */ } // Note: no size_t parameter!
          >
          // Normal delete
          void operator delete(void*) { /* ... */ }
          >
          then
          >
          SmC* s1 = new(WORK_HEAD) SmC; // Calls placement new
          delete s1; // Calls normal delete, destructor calledfirst.
          >
          If the constructor for SmC throws an exception, the placement delete function
          will be called.
          >
          -dr
          >
          HI Dave ,
          >
          I am trying for memory optimization .
          I have a chunk of memory which will be divided in to smaller pools of
          memory .
          So, my overloaded new will allocate memory from a particular pool.
          Now during delete I need to know from which pool I need to free the
          memory.
          Due to this I need to use placement delete so that I can pass the pool
          related info to the
          overloaded delete. But I want to delete to call destructor also.
          >
          Allocation and freeing here means getting the memory from a linked
          list of free nodes and adding it to linked list of allocated
          node .Deleting means adding the node back to the link list.
          These two lists are maintained inside a pool.
          If each pool is a contiguous ranges of memory then you can figure out
          which pool an object has been allocated in by checking the address
          against the ranges.

          --
          Erik Wikström

          Comment

          • Kishore  Yada

            #6
            Re: Overloaded delete does not calls the destructor??


            rohits123@gmail .com wrote:
            On Feb 7, 3:46 pm, Dave Rahardja <a...@me.comwro te:
            On 6 Feb 2007 18:11:37 -0800, rohits...@gmail .com wrote:


            >I have an overload delete operator as below
            >//////////////////////////////////
            >void operator delete(void* mem,int head_type) {
            mmHead local_Head = CPRMemory::GetM emoryHead(head_ type);
            mmFree(&local_H ead,(char *)mem);
            CPRMemory::SetM emoryHeadAs(loc al_Head,head_ty pe);
            >}
            >/////////////////////
            >void* operator new(size_t sz, int head_Type) {
            char *mem;
            mmHead local_Head = CPRMemory::GetM emoryHead(head_ Type);
            mem = mmAlloc(&local_ Head,sz);
            CPRMemory::SetM emoryHeadAs(loc al_Head,head_Ty pe);
            if(!mem) cout<<"Out of Memory"<<endl;
            return mem;
            >}
            >////////////////
            >and using it as
            SmC* s1 = new(WORK_HEAD) SmC;
            >operator delete (s1,WORK_HEAD) ;
            >But the problem is overloaded delete operator is not calling the
            >destructor of class SmC.
            >Do I have to call the destructor explicitly?
            >Any suggestions please.
            You've overridden placement delete, which is used only to deallocate memory in
            case a constructor throws an exception. The destructor is not called if you
            call placement delete.

            What you need to do is to override placement new, placement delete, _and_
            normal delete:

            // Placement new
            void* operator new(size_t sz, int) { /* ... */ }

            // Placement delete
            void operator delete(void*, int) { /* ... */ } // Note: no size_t parameter!

            // Normal delete
            void operator delete(void*) { /* ... */ }

            then

            SmC* s1 = new(WORK_HEAD) SmC; // Calls placement new
            delete s1; // Calls normal delete, destructor called first.

            If the constructor for SmC throws an exception, the placement delete function
            will be called.

            -dr
            >
            HI Dave ,
            >
            I am trying for memory optimization .
            I have a chunk of memory which will be divided in to smaller pools of
            memory .
            So, my overloaded new will allocate memory from a particular pool.
            Now during delete I need to know from which pool I need to free the
            memory.
            Due to this I need to use placement delete so that I can pass the pool
            related info to the
            overloaded delete. But I want to delete to call destructor also.
            >
            Allocation and freeing here means getting the memory from a linked
            list of free nodes and adding it to linked list of allocated
            node .Deleting means adding the node back to the link list.
            These two lists are maintained inside a pool.
            Instead of using
            operator delete (s1,WORK_HEAD) ;

            call
            delete s1;

            That should call both the destructor and the overloaded delete. You
            cannot pass any extra arguments to the destructor ( means also to your
            delete function ).

            However, be aware of inheritance nightmares while overloading new and
            delete.
            Also, instead of cluttering your class with memory allocation and
            deallocation code, see if you can separate it to another class.

            Comment

            • Andrey Tarasevich

              #7
              Re: Overloaded delete does not calls the destructor??

              rohits123@gmail .com wrote:
              ...
              and using it as
              >
              SmC* s1 = new(WORK_HEAD) SmC;
              operator delete (s1,WORK_HEAD) ;
              >
              But the problem is overloaded delete operator is not calling the
              destructor of class SmC.
              'operator delete' is a raw memory deallocation function. It _never_ calls the
              destructor and it's not supposed to do so.

              When you destroy an object with delete-expression, which normally looks as follows

              delete s1;

              This is a delete-expression. It will do two things: 1) invoke the object's
              destructor, 2) deallocate memory by selecting and calling 'operator delete'
              function.

              Note that 'operator delete' implements just a part of the functionality of
              delete-expression. It is called when the destructor has already been called.
              Do I have to call the destructor explicitly?
              In your code you are not using delete-expression at all. This is fine, but that
              means that you have to perform both of the aforementioned steps manually. I.e.
              first you have to call the destructor manually and then you can deallocate the
              memory by calling 'operator delete':

              s1->SmC::~SmC();
              operator delete(s1, WORK_HEAD);

              --
              Best regards,
              Andrey Tarasevich

              Comment

              • Ron Natalie

                #8
                Re: Overloaded delete does not calls the destructor??

                Dave Rahardja wrote:
                You've overridden placement delete, which is used only to deallocate memory in
                case a constructor throws an exception. The destructor is not called if you
                call placement delete.
                >
                It's got squat to do with it being placement.

                operator delete() is NOT the implementation of the delete operator
                (despite it's unfortunately name), it is the memory deallocation
                function that the delete operator uses.

                Calling the deallocation function DOES not call the desructors
                EVER, regardless of whether it is the normal or placement
                version.

                Comment

                • Dave Rahardja

                  #9
                  Re: Overloaded delete does not calls the destructor??

                  On Thu, 08 Feb 2007 07:28:53 -0500, Ron Natalie <ron@spamcop.ne twrote:
                  >Dave Rahardja wrote:
                  >
                  >You've overridden placement delete, which is used only to deallocate memory in
                  >case a constructor throws an exception. The destructor is not called if you
                  >call placement delete.
                  >>
                  >It's got squat to do with it being placement.
                  >
                  >operator delete() is NOT the implementation of the delete operator
                  >(despite it's unfortunately name), it is the memory deallocation
                  >function that the delete operator uses.
                  >
                  >Calling the deallocation function DOES not call the desructors
                  >EVER, regardless of whether it is the normal or placement
                  >version.
                  You're right. What I meant was that the standard delete expression looks an
                  awful lot like a call to placement delete without the extra arguments.

                  -dr

                  Comment

                  • Dave Rahardja

                    #10
                    Re: Overloaded delete does not calls the destructor??

                    On 6 Feb 2007 23:13:02 -0800, rohits123@gmail .com wrote:
                    >HI Dave ,
                    >
                    >I am trying for memory optimization .
                    >I have a chunk of memory which will be divided in to smaller pools of
                    >memory .
                    >So, my overloaded new will allocate memory from a particular pool.
                    >Now during delete I need to know from which pool I need to free the
                    >memory.
                    >Due to this I need to use placement delete so that I can pass the pool
                    >related info to the
                    >overloaded delete. But I want to delete to call destructor also.
                    >
                    >Allocation and freeing here means getting the memory from a linked
                    >list of free nodes and adding it to linked list of allocated
                    >node .Deleting means adding the node back to the link list.
                    >These two lists are maintained inside a pool.
                    You've hit upon a classic design problem with C++ and memory allocation: The
                    fact that it's difficult to tell via during deletion how the memory was
                    allocated.

                    There are several solutions to the problem, but none of them are clean or
                    simple. Check out chapter 8 of Scott Meyers' Effective C++ (3rd Ed) for a
                    detailed look at the problem of customizing new and delete. Here are some
                    suggestions.

                    You can override new and delete for a class. This approach entangles the
                    problem domain of memory management with the problem domain your class was
                    intended to address.

                    You can override new and delete for a class, and then templatize the class to
                    use a memory manager class. This way the user of the class can choose (via the
                    template parameter) which memory manager will be used.

                    You can create a Factory that associates a class with a memory manager. You
                    call functions in the Factory (such as create() and destroy()) to perform
                    memory allocation and deallocation. In this scenario, the class is completely
                    disentangled from the memory allocation algorithm. However, you can no longer
                    use delete to destroy your class, or pass the pointers to other algorithms
                    that can delete your class for you.

                    You can override global new and delete. Each time new is called, allocate
                    memory that is slightly larger than needed. In the "spare" area of allocated
                    memory, store a pointer to the pool that you allocated the object from. During
                    deletion, peek at the pointer you stashed away to discover where the allocated
                    block came from. The downside to this is that your custom global new and
                    delete may be called to allocate _any_ class. It is difficult to restrict
                    allocation to a certain class or classes that are causing a bottleneck.

                    There are other solutions as well, but none of them are any cleaner or easier
                    to use.

                    -dr

                    Comment

                    Working...