In C++, operators new/delete mostly replace the use of malloc() and
free() in C. For example:
class A {
public:
A();
~A();
};
A* p = new A;
...
delete p;
allocates storage for an A object and arranges for its constructor to
be called, later followed by invocation of the destructor and freeing
of the storage. You can use the standard new/delete functions in the
library, or define your own globally and/or on a per-class basis.
There's a variation on new/delete worth mentioning. It's possible to
supply additional parameters to a new call, for example:
A* p = new (a, b) A;
where a and b are arbitrary expressions; this is known as "placement
new". For example, suppose that you have an object instance of a
specialized class named Alloc that you want to pass to the new
operator, so that new can control allocation according to the state of
this object (that is, a specialized storage allocator):
class Alloc {/* stuff */};
Alloc allocator;
...
class A {/* stuff */};
...
A* p = new (allocator) A;
If you do this, then you need to define your own new function, like
this:
void* operator new(size_t s, Alloc& a)
{
// stuff
}
The first parameter is always of type "size_t" (typically unsigned
int), and any additional parameters are then listed. In this example,
the "a" instance of Alloc might be examined to determine what strategy
to use to allocate space. A similar approach can be used for operator
new[] used for arrays.
This feature has been around for a while. A relatively new feature
that goes along with it is placement delete. If during object
initialization as part of a placement new call, for example during
constructor invocation on a class object instance, an exception is
thrown, then a matching placement delete call is made, with the same
arguments and values as to placement new. In the example above, a
matching function would be:
void operator delete(void* p, Alloc& a)
{
// stuff
}
With new, the first parameter is always "size_t", and with delete,
always "void*". So "matching" in this instance means all other
parameters match. "a" would have the value as was passed to new
earlier.
Here's a simple example:
int flag = 0;
typedef unsigned int size_t;
void operator delete(void* p, int i)
{
flag = 1;
}
void* operator new(size_t s, int i)
{
return new char[s];
}
class A {
public:
A() {throw -37;}
};
int main()
{
try {
A* p = new (1234) A;
}
catch (int i) {
}
if (flag == 0)
return 1;
else
return 0;
}
Placement delete may not be in your local C++ compiler as yet. In
compilers without this feature, memory will leak. Note also that you
can't call overloaded operator delete directly via the operator
syntax; you'd have to code it as a regular function call.