Topic: Overloaded new/delete
Author: "Alan Gray" <agray@oznet02.ozemail.com.au>
Date: 1995/11/25 Raw View
Given
class Malloc {
public:
void *allocate(size_t sz);
void deallocate(void *ptr);
};
void *operator new(size_t sz,Malloc *myalloc)
{
return(myalloc->allocate(sz));
}
void operator delete(void *ptr,Malloc *myalloc) // new in WP ??
{
myalloc->deallocate(ptr);
}
class Base {
public:
Base();
virtual ~Base();
};
class Derived : public Base {
public:
Derived();
~Derived();
};
void fred(Malloc *myalloc)
{
double *a = new(myalloc) double[1024];
double *b = new(myalloc) double;
Base *c = new(myalloc) Derived[1024];
Base *d = new(myalloc) Derived;
... lots of code
// HOW do i free a,b,c & d so that
// (1) all the destructors are called
// (2) the memory is deallocated
delete(myalloc) [] a; // not C++
delete(myalloc) b; // not C++
delete(myalloc) [] c; // not C++
delete(myalloc) d; // not C++
// call manually
::operator delete(a,myalloc);
::operator delete(b,myalloc);
// will this call the destructor for the 1024 Derived elements created
// & deallocate all the memory
::operator delete(c,myalloc);
// will this call the destructor for the 1 Derived element created
// & deallocate all the memory
::operator delete(d,myalloc);
}
Other questions this code raises is
(1)
Will size_t sz passed to new(size_t sz,Malloc *mymalloc)
include the overhead for the number of objects allocated ??
and will the compiler adjust the retured pointer so that
a,b,c & d point to the start of array, not at the number of objects ?
(P.S) Microsoft Visual C++ 2.0 works OK here
(2)
How can the compiler known that c was an array of objects allocated,
especially if c is deleted in a different compilation unit.
Is there a specific syntax for this.
I'm guessing but, do I need to declare
void *operator new[](size_t sz,Malloc *myalloc) &
void *operator delete[](size_t sz,Malloc *myalloc)
Alan Gray
4D Solutions PTY LTD
PO BOX 103 Narrabeen NSW
2101 Australia
agray@ozemail.com.au
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/11/26 Raw View
"Alan Gray" <agray@oznet02.ozemail.com.au> writes:
>Given
>
>void *operator new(size_t sz,Malloc *myalloc)
...
>void operator delete(void *ptr,Malloc *myalloc) // new in WP ??
...
>void fred(Malloc *myalloc)
>{
> double *a = new(myalloc) double[1024];
> double *b = new(myalloc) double;
> Base *c = new(myalloc) Derived[1024];
> Base *d = new(myalloc) Derived;
...
>// HOW do i free a,b,c & d so that
>// (1) all the destructors are called
>// (2) the memory is deallocated
You can clean up `b' and `d' like this:
Delete(b);
Delete(d);
That assumes the following definition of Delete():
template <class T>
void Delete (const T *ptr, Malloc *myalloc)
{
ptr->~T();
::operator delete (myalloc, ptr);
}
Unfortunately, using a similar technique for `a' is not guaranteed to
work:
template <class T>
void DeleteArray (const T *ptr, Malloc *myalloc, size_t size)
{
for (size_t i = 0; i < size; i++) {
ptr[i].~T();
}
::operator delete [] (myalloc, ptr);
}
DeleteArray(a);
The reason this may not work is that the value returned by
new (myalloc) double[1024]
may not be the same as the value returned from
operator new (myalloc, size)
since the implementation may allocate extra space for a count
of the number of elements. There is no guarantee that the pointer
you pass to ::operator delete [] () points to a value that
was allocated with ::operator new [] ().
So as far as I can tell, for `a' and `c', you are SOL.
For `c', you were already in a bad shape anyway - an
expression like `c[1]' would be undefined behaviour,
and you would have had to use
DeleteArray(dynamic_cast<Derived *>(c));
to deallocate the memory (but of course that doesn't solve
the above-mentioned problem). Basically, even though
a Derived IS-A Base, an array of Derived IS-NOT-AN array of Base.
>// will this call the destructor for the 1024 Derived elements created
>// & deallocate all the memory
>
> ::operator delete(c,myalloc);
No, it won't call the destructor.
>// will this call the destructor for the 1 Derived element created
>// & deallocate all the memory
>
> ::operator delete(d,myalloc);
It won't call the destructor - if you call the deallocation function manually,
then you have to call the destructor manually too.
But it will deallocate all the memory.
>}
>
>Other questions this code raises is
>
>(1)
>
>Will size_t sz passed to new(size_t sz,Malloc *mymalloc)
>include the overhead for the number of objects allocated ??
The answer is "maybe" - it is up to the implementation.
Typically the answer will be "no" unless the object has a (non-trivial)
destructor, in which case it will be "yes".
>I'm guessing but, do I need to declare
>
>void *operator new[](size_t sz,Malloc *myalloc) &
>void *operator delete[](size_t sz,Malloc *myalloc)
Yes, that would be a good idea. But it still doesn't solve the
problem. You are still SOL. I think this is a quite severe problem
with the current draft standard.
--
Fergus Henderson WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au PGP: finger fjh@128.250.37.3
I will have little or no net access from Nov 30 until Dec 25.
Please email me a copy of any follow-ups.
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1995/11/27 Raw View
Oops, I made a couple of mistakes in my previous post:
>You can clean up `b' and `d' like this:
>
> Delete(b);
> Delete(d);
That should be
Delete(b, myalloc);
Delete(d, myalloc);
> DeleteArray(a);
That should be
DeleteArray(a, myalloc, 1024);
Apologies for any confusion that caused.
--
Fergus Henderson WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au PGP: finger fjh@128.250.37.3
I will have little or no net access from Nov 30 until Dec 25.
Please email me a copy of any follow-ups.
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]