Lloyd said:
how do I redefine the new operator?
The Effective C++ and/or More Effective C++ books discuss that topic,
among other books. It's not something you can explain in a few lines.
And it's not something you generally want to do yourself.
it's very handy to use "new SCRIPT_ITEM[N];" however I want to handle
OutOfMemory gracefully,
that is dealloc everything 1st and then throw a managed exception
There is nothing you have to deallocate if allocation fails. You can
catch the C++ exception and throw a managed one.
I also want to initialize all my struct to 0 with new.
It would be nice if C++ initialized everything to 0 automatically,
unless a special keyword is used (for the performance-oriented tasks).
But it's not the memory allocator's job, it needs to be done in the
constructor. What if you allocate the object on the stack? In that case
no new operator is called.
Also, if I have not enough memory in a C++ constructor, should the object
delete itself?
If a class' constructor throws, the object is not considered existing.
Therefore you can't call delete on it, and its destructor is not called
either. So you should be careful about throwing from a constructor, at
least in native C++.
I recommend that you protect your allocations with smart pointers,
because in case a cosntructor throws, its members that have already been
initialized are gracefully destructed automatically.
Example:
class C
{
public:
C() : member(new int) { throw 0; }
~C() { delete member; }
private:
int* member;
};
This class is going to leak, because its constructor throws before
deleting the allocated member. You can avoid this leak by using auto_ptr:
class C
{
public:
C() : member(new int) { throw 0; }
private:
std::auto_ptr<int> member;
};
This time "member" is destructed automatically and there is no leak.
This is the only safe way of programming. I recommend boost::shared_ptr
for complex application, read my article "An Introduction to Boost
shared_ptr" for a full discussion:
http://tweakbits.com/
It's a good idea to write a class for every operation that needs to be
performed in pairs (open/close, allocate/deallocate, lock/unlock). This
technique is called RAII (resource acquisition is initialization), when
an extremely thin class is created just for resource lifetime
management. The resource is initialized in the constructor and is
uninitialized/released in the destructor. The class should be very thin
and should be used as member for larger classes. This way you're always
on the safe side.
Also be careful to create a physical variable for each allocation,
instead of passing allocations on the fly:
f(std::auto_ptr<T>(new T), std::auto_ptr<U>(new U); // UNSAFE!!!
This is not safe, because the order of execution of the calls is
undefined, and new may fail before auto_ptr has a chance to secure the
object. Don't try to save lines, do it the proper way:
std::auto_ptr<T> param1(new T);
std::auto_ptr<U> param2(new U);
f(param1, param2); // this is safe
Tom