Topic: delete-placement


Author: "Ed Brey" <brey@afd.mke.etn.com>
Date: 2000/01/08
Raw View
What is the reason for not having a delete-placement portion of the delete
expression to pair the new-placement portion of a new expression?

My impetus for this question stemmed from my attempt to wrap access to the
COM heap space through new and delete expressions.  For example, I wanted to
define:

void* operator new[](std::size_t, const taskmem_t&);
void* operator delete[](void*, const taskmem_t&);

and then use expressions such as:

long* l = new(taskmem) long[10];
delete[](taskmem) l;

This kind of expression is useful for both built-in and user-defined scalar
and arrays, as often the exact same type will be allocated sometimes on the
default heap and sometimes on COM's heap.  Of course, it is up to the
program to make sure that the type of delete matches the new.

The definition of the operators would call the COM memory allocation
functions, for example, operator new[]'s code would be: {
  void* p = ::CoTaskMemAlloc(size);
  if (!p) throw std::bad_alloc();
  return p;
}

Additional, I would define all the array and non-array, throwing and
nothrowing variants.  Also, although not shown, "taskmem" is properly stowed
in an appropriate namespace.

I was pleased to find that this all works fine for new, but delete didn't
work.  Checking the IS, I was dismayed to see the grammar showed "::opt
delete [ ] cast-expression".  Alas, no delete-placement and hence
possibility for passing parameters to operator delete.

Fortunately, new is the really important expression to have working, since
it controls the construction, and maybe that's why delete never got a
delete-placement.  The following, from the appropriate namespace, is a
viable workaround, although just not as pretty.

template<typename T> destroy(const T* p) {
  const T* end = p + com_allocator->GetSize(p) / sizeof(T);
  for (const T* x = p; x != end; ++x)
    x->~T()
  ::CoTaskMemFree(p);
}

so the code looks like this:

long* l = new(taskmem) long[10];
destroy(l);

It should work, but if anyone know of a better way, I'd be happy to hear it.
And of course, I'm very curious in the rationale behind not offering delete
the same parameterization capability as new.

One final note, to stay off any confusion: If there were a delete-placement,
it's grammar would be identical to that of new-placement, so the two would
be rolled into one definition and given a generic name.  So really, there
will never be a "delete-placement", even if the feature is added.



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]