Topic: `operator delete()' and size_t parameter (was Ok this compiles but is it std C++)


Author: jamshid@emx.cc.utexas.edu (Jamshid Afshar)
Date: 6 Sep 1993 15:04:34 -0500
Raw View
In article <1993Aug31.150611.9251@vedge.com>,
Hendrik Boom <hendrik@vedge.com> wrote:
>alan@saturn.cs.swin.oz.au (Alan Christiansen) writes:
>: [My compiler manual says...] A user-defined operator DELETE must have
>: a VOID return type and VOID* as its first argument; a second argument
>: of type SIZE_T is optional. For example, .... "
>[...]
>As far as I know, no such extra arguments are allowed in the delete syntax.
>If Borland allows them, they are nonstandard.

(sorry if this has been corrected in another followup)

No, a class `operator delete()' function is allowed to have a `size_t'
parameter.  The delete operator syntax (eg, `delete p;') doesn't
change, though; it is supplied automagically by the compiler.

The extra argument is necessary because

 Derived* dp = new Derived;
and delete dp;

call the base's `operator new()' and `operator delete()' functions
unless Derived defines its own.  This means your Base functions might
get called to allocate and free blocks of memory larger than
sizeof(Base).  See the following example and ARM 12.5.

 class Base {
    static Pool my_pool;
    int i;
 public:
    virtual int f();
    virtual ~Base();   // destructor must be virtual!
    void* operator new(size_t s);
    void operator delete(void* p, size_t s);
 };

 class Derived : public Base {
    int j;
 public:
    virtual ~Derived();
    virtual int f();
 };

 Base* p = new Derived;  // calls Base::operator new(sizeof(Derived))
 delete p;   // calls Derived::~Derived() and then calls
             // Base::operator delete( (void*)p, sizeof(Derived) )
             // to free block


 Pool Base::my_pool(sizeof(Base));   // allocates fixed-size blocks

 void* Base::operator new(size_t s) {
    if (s>sizeof(Base))
       return ::operator new(s);   // pass off to global func
    else
       return my_pool.alloc();
 }

 void Base::operator delete(void* p, size_t s) {
    if (s>sizeof(Base))   // these blocks were not allocated by pool
       ::operator delete(p);
    else
       my_pool.free(p);
 }

Jamshid Afshar
jamshid@emx.cc.utexas.edu