overloading new/delete
void* ptr = new void[size];
Can't do that. Fix it.
Never ever try to overload new/delete globally. Either have them in a base class and derive all your objects from this class or use a namespace or a template allocator parameter. Why, you may ask. Because in case your program is more than a single file and using STL or other libraries you are going to screw up.
Here's a distilled version of new
operator from VS2005 new.cpp
:
void * operator new(size_t size) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
Keeping track of used memory with overloaded new and delete operator?
A bit annoying, isn't it? free
knows how much memory there is to free, but won't tell you.
The practical solution is to add an extra sizeof(size_t)
to the malloc
request, and use those first bytes of the returned allocation to store sz
. In operator delete
, you do the reverse: you look for the sizeof(size_t)
bytes preceding ptr
.
So the bit of code you'd get is memory-=static_cast<size_t*>(prt)[-1];
. The [-1]
looks scary, I know. One of the few cases where it makes sense.
Overloading new and delete vs Custom Allocator
Broadly speaking, an Allocator
type is used when an object of one type (typically a container) needs to manage memory to hold an object or objects of some other type. Overloading operator new
and operator delete
within a class is used when objects of that type need some special memory management.
New/delete operator overload and base class
operator delete
is special in that despite being a static member, if the class has a virtual destructor it is dynamically dispatched. §12.5 [class.free]/p4:
If the delete-expression is used to deallocate a class object whose
static type has a virtual destructor, the deallocation function is the
one selected at the point of definition of the dynamic type’s virtual
destructor (12.4).
For example,
struct B {
virtual ~B() = default;
void operator delete(void* ptr) {
std::cout << "B's operator delete" << std::endl; ::operator delete(ptr);
}
};
struct D : B {
void operator delete(void* ptr) {
std::cout << "D's operator delete" << std::endl; ::operator delete(ptr);
}
};
int main() {
B* bp = new D;
delete bp; //1: uses D::operator delete(void*)
}
prints:
D's operator delete
Thus, give A
a virtual destructor and you should see the correct operator delete
called :).
C++ overloaded delete operator for array of pointers not being called
You're not providing an overload for operator new[](size_t sz)
, so you're lucky that your operator new(size_t sz)
is being called at all.
The compiler is calling the unsized versions delete[]
, so you need to provide a operator delete[](void *ptr) noexcept
function. Note that the standard requires the non-size version to be replaced when replacing the version that takes a size.
Related Topics
How to Use If (Pointer) Instead of If (Pointer != Null)
Getting Libcurl to Work with Visual Studio 2013
How to Write Custom Input Stream in C++
Any Reason to Overload Global New and Delete
Why Do You Use Std::Move When You Have && in C++11
Stl::Multimap - How to Get Groups of Data
Printing All Environment Variables in C/C++
How to Convert a C++ String to an Int
How to Write a Type Trait 'Is_Container' or 'Is_Vector'
Does True Equal to 1 and False Equal to 0
Trivial VS. Standard Layout VS. Pod
How to Evaluate Mathematical Expressions in C++
Emulate "Double" Using 2 "Float"S
C++11 Stl Containers and Thread Safety