Hi Tom, thanks for your mail, my help me solve elegantly some problem I have.
2 questions though:
1st:
if there is a C function like that
void F(TYPE* p); // remark p is a pointer to an array
how do I call it with an
auto_ptr<TYPE> p; //??? p
could I just:
p = new
F(p); //???
2nd:
I will first submit an idea of solution without auto_ptr (an idea I had from an other post) for you to comment, and then a second listing with auto_ptr (to comment as well ;-)
BTW I had a quick read at your boost stuff but I don't really need it, very simple application, I will limit myself to standart stuff, easier to pick for next developer, no extra download... (but it's good stuff, I have to admit)
-- 1st listing -- what about that ? --
#include <someLibrary.h>
// my managed not enough memory exception!
static OutOfMemoryException^ NotEnoughMemory = gcnew OutOfMemoryException();
class MyClass
{
TYPE_1_T *var1, *var2, *var, *var4, *var5;
public:
MyClass(int aNumber) : var1(NULL), var2(NULL), var3(NULL), var4(NULL), var5(NULL)
{
try
{
// get the size of the arrays
int[] SIZES = new int[5]; // temp variable, could be leaked by an exception, problem.....
SomeOtherLibFunction( aNumber, 5, SIZES );
// some (memory) error throwing init code
var1 = new TYPE_1_T[ SIZES[1] ];
var2 = new TYPE_1_T[ SIZES[2] ];
var3 = new TYPE_1_T[ SIZES[3] ];
var4 = new TYPE_1_T[ SIZES[4] ];
var5 = new TYPE_1_T[ SIZES[5] ];
// ... some other code ...
blabla( var1 );
// delete temporary variable
// oops.. would leak if there is an exception before,
// in may case it's difficult to work around it's freed / allocated / adjusted in a loop
delete SIZES;
}
catch(std::bad_alloc)
{
// here I delete all my allocated var, what do you think?
~MyClass();
throw NotEnoughMemory ;
}
}
~MyClass()
{
if(var1)
delete var1;
if(var2)
delete var2;
if(var3)
delete var3;
if(var4)
delete var4;
if(var5)
delete var5;
// to prevent problem with multiple call
var1 = NULL;
var2 = NULL;
var3 = NULL;
var4 = NULL;
var5 = NULL;
}
}
-- 2nd listing -- what about that ? -- (I hope it's good as it's much more simple!) --
#include <someLibrary.h>
// include for auto_ptr ?! which header ?!
#include <auto_ptr>
// my managed not enough memory exception!
static OutOfMemoryException^ NotEnoughMemory = gcnew OutOfMemoryException();
using namespace std;
class MyClass
{
// here potential problem, would managed class accept auto_ptr<> variable type?
auto_ptr<TYPE_1_T> var1, var2, var, var4, var5;
public:
MyClass()
{
try
{
// get the size of the arrays, safe operation, nice!
auto_ptr<int[]> SIZES(new int[5]);
SomeOtherLibFunction( aNumber, 5, SISEZ );
// are these statments ok?
var1 = new TYPE_1_T[ SIZES[1] ];
var2 = new TYPE_1_T[ SIZES[2] ];
var3 = new TYPE_1_T[ SIZES[3] ];
var4 = new TYPE_1_T[ SIZES[4] ];
var5 = new TYPE_1_T[ SIZES[5] ];
// ... some other code ...
blabla( var1 );
}
catch(std::bad_alloc)
{
throw NotEnoughMemory ;
}
}
}
---
--
There are 10 kinds of people in this world. Those who understand binary and those who don't.
"Tamas Demjen" <tdemjen@yahoo.com> wrote in message news:eaZtg9dmFHA.3380@TK2MSFTNGP12.phx.gbl...[color=blue]
> Lloyd Dupont wrote:[color=green]
>> how do I redefine the new operator?[/color]
>
> 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.
> [color=green]
>> 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[/color]
>
> There is nothing you have to deallocate if allocation fails. You can
> catch the C++ exception and throw a managed one.
> [color=green]
>> I also want to initialize all my struct to 0 with new.[/color]
>
> 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.
> [color=green]
>> Also, if I have not enough memory in a C++ constructor, should the object
>> delete itself?[/color]
>
> 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[/color]