[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Better way of allocating a memory( auto_ptr vs new vs malloc

Ami

12/6/2008 3:09:00 PM

Friends

I have been working on C++ code optimization to minimize the memory
leaks and better performance on HP-UX with aCC
I have the following example to share with you

I have a structure SYS_LC_DETAILS_CDA for which I have allocated a
memory using malloc and then memset and then calling a function to
assign values to the structure elements as below
SYS_LC_DETAILS_CDA *p_str_lc_details = (SYS_LC_DETAILS_CDA *)malloc
(sizeof(SYS_LC_DETAILS_CDA));
memset(p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));
conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);
and calling free()

in another example
im using a new operator as below
SYS_LC_DETAILS_CDA *p_str_lc_details = new SYS_LC_DETAILS_CDA ;
memset(p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));
conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);
then delete

in a 3rd way
I do as below
SYS_LC_DETAILS_CDA p_str_lc_details;
memset(&p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));
in above case I dont have to deallocate any...

in a 4th way I am using an auto_ptr as below
auto_ptr<SYS_LC_DETAILS_CDA>p_str_lc_details = (new
SYS_LC_DETAILS_CDA) ;
and then passing the pointer variable as
conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);

Which is the better way of allocating . auto_ptr score well above the
rest as the object gets destroyed as soon as it goes out of scope ...

So which is the best way to minimize the meamory leaks ?

Many thanks
10 Answers

peter koch

12/6/2008 5:08:00 PM

0

On 6 Dec., 16:09, Ami <Amit.Bas...@gmail.com> wrote:
> Friends
>
> I have been working on C++  code optimization to minimize the memory
> leaks and better performance on HP-UX with aCC
>  I have the following example to share with you
>
> I have a structure  SYS_LC_DETAILS_CDA  for which I have allocated  a
> memory using malloc  and then memset and then calling a function to
> assign values to the structure elements as  below
>   SYS_LC_DETAILS_CDA *p_str_lc_details = (SYS_LC_DETAILS_CDA *)malloc
> (sizeof(SYS_LC_DETAILS_CDA));
>  memset(p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));
> conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);
> and calling free()

This is the C way. I can't really recommend it.
>
> in another example
> im using a new operator as below
>  SYS_LC_DETAILS_CDA *p_str_lc_details = new  SYS_LC_DETAILS_CDA ;

This is the standard way to allocate dynamic memory in C++. You just
forgot to default initialise it (using new SYS_LC_DETAILS_CDA()). This
would let you forget the memset (another C-function, you'd do better
to forget). You have a potential resource leak, however, which could
be avoided e.g. by using std::auto_ptr as you mention later.

>  memset(p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));
> conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);
> then delete
>
> in a 3rd way
> I do as below
> SYS_LC_DETAILS_CDA p_str_lc_details;
>  memset(&p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));

This is the correct way whenever you don't need dynamic memory. Always
use this. And again, you should avoid the memset by using default
initialisation - but beware: you need to use
SYS_LC_DETAILS_CDA p_str_lc_details(SYS_LC_DETAILS_CDA());

and not
SYS_LC_DETAILS_CDA p_str_lc_details();

as this is a function declaration.

> in above case I dont have to deallocate any...
>
> in a 4th way I am using an auto_ptr as below
> auto_ptr<SYS_LC_DETAILS_CDA>p_str_lc_details = (new
> SYS_LC_DETAILS_CDA) ;
> and then passing the pointer variable as
> conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);

In the above case, the second one is clearly the best. Otherwise -
when the object must outlive scope - the std::auto_ptr solution or
something similar should be preferred.

/Peter

Ami

12/6/2008 8:22:00 PM

0

Thanks Peter

I have few qustions
Consider the allocation SYS_LC_DETAILS_CDA p_str_lc_details
(SYS_LC_DETAILS_CDA());
SYS_LC_DETAILS_CDA() in above would do default initialization right
then I can safely avoid the use of C style memset..
and then nevere have to de allocate the same.

As far as auto_ptr is concrned , do I again need to initialize to
SYS_LC_DETAILS_CDA () as shown below
auto_ptr<SYS_LC_DETAILS_CDA>p_str_lc_details = (new SYS_LC_DETAILS_CDA
()) ;
another major concerned abt using auto_ptr is

after the memory allocation is done tht is lets say
int main ()
{

auto_ptr<SYS_LC_DETAILS_CDA>p_str_lc_details = (new SYS_LC_DETAILS_CDA
()) ;
conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details.get
(),pStrLcDetails); //
return ( EXIT_SUCESS);
}

void CopyToDceSYS_LC_DETAILS_CDA(SYS_LC_DETAILS_CDA *output)
{
// some code
}

do u see any problem with uisng an auto pointer like above i.e passing
as an argument in a function call .
Is there any memory Leak ?
I think the auto of auto ptr is the best way ..
Also in the code the malloc is done like
SYS_GUARANTORS_CDA *p_str_guarantors = (SYS_GUARANTORS_CDA *)malloc
(sizeof(SYS_GUARANTORS_CDA)*(p_nbr_Guarantors+1));
so using new for above is like
SYS_GUARANTORS_CDA *p_str_guarantors = (SYS_GUARANTORS_CDA *)new char
[sizeof(SYS_GUARANTORS_CDA)*(p_nbr_Guarantors+1)];
is the above correct way i.e using an array

Thanks

blargg.h4g

12/6/2008 10:37:00 PM

0

Ami wrote:
> I have few qustions
> Consider the allocation SYS_LC_DETAILS_CDA p_str_lc_details
> (SYS_LC_DETAILS_CDA());
> SYS_LC_DETAILS_CDA() in above would do default initialization right
> then I can safely avoid the use of C style memset..
> and then nevere have to de allocate the same.
>
> As far as auto_ptr is concrned , do I again need to initialize to
> SYS_LC_DETAILS_CDA () as shown below
> auto_ptr<SYS_LC_DETAILS_CDA>p_str_lc_details = (new SYS_LC_DETAILS_CDA
> ()) ;
> another major concerned abt using auto_ptr is
>
> after the memory allocation is done tht is lets say
> int main ()
> {
>
> auto_ptr<SYS_LC_DETAILS_CDA>p_str_lc_details = (new SYS_LC_DETAILS_CDA
> ()) ;
> conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details.get
> (),pStrLcDetails); //
> return ( EXIT_SUCESS);
> }
>
> void CopyToDceSYS_LC_DETAILS_CDA(SYS_LC_DETAILS_CDA *output)
> {
> // some code
> }
>
> do u see any problem with uisng an auto pointer like above i.e passing
> as an argument in a function call .
> Is there any memory Leak ?
> I think the auto of auto ptr is the best way ..
> Also in the code the malloc is done like
> SYS_GUARANTORS_CDA *p_str_guarantors = (SYS_GUARANTORS_CDA *)malloc
> (sizeof(SYS_GUARANTORS_CDA)*(p_nbr_Guarantors+1));
> so using new for above is like
> SYS_GUARANTORS_CDA *p_str_guarantors = (SYS_GUARANTORS_CDA *)new char
> [sizeof(SYS_GUARANTORS_CDA)*(p_nbr_Guarantors+1)];
> is the above correct way i.e using an array
>
> Thanks

My god that is so hard to read. Look at the difference a couple of
find-and-replaces and some indention do:

> I have few qustions
> Consider the allocation
>
> T p(T());
>
> T() in above would do default initialization right
> then I can safely avoid the use of C style memset..
> and then nevere have to de allocate the same.
>
> As far as auto_ptr is concrned , do I again need to initialize to
> T () as shown below
>
> auto_ptr<T>p = (new T()) ;
>
> another major concerned abt using auto_ptr is
>
> after the memory allocation is done tht is lets say
>
> int main ()
> {
> auto_ptr<T>p = (new T()) ;
> func(p.get()); //
> return ( EXIT_SUCESS);
> }
>
> void func(T *output)
> {
> // some code
> }
>
> do u see any problem with uisng an auto pointer like above i.e passing
> as an argument in a function call .
> Is there any memory Leak ?
> I think the auto of auto ptr is the best way ..
> Also in the code the malloc is done like
>
> T *p = (T *)malloc (sizeof(T)*(n+1));
>
> so using new for above is like
>
> T *p = (T *)new char [sizeof(T)*(n+1)];
>
> is the above correct way i.e using an array

Long names greatly hurt readability here.

Erik Wikström

12/7/2008 9:34:00 AM

0

On 2008-12-06 23:36, blargg wrote:
> Ami wrote:

> My god that is so hard to read. Look at the difference a couple of
> find-and-replaces and some indention do:

And it lets us find some things to improve upon.

>> I have few qustions
>> Consider the allocation
>>
>> T p(T());

T p(); will do just as well.

>> T() in above would do default initialization right
>> then I can safely avoid the use of C style memset..
>> and then nevere have to de allocate the same.
>>
>> As far as auto_ptr is concrned , do I again need to initialize to
>> T () as shown below
>>
>> auto_ptr<T>p = (new T()) ;

No need to use () around the new, auto_ptr<T>p = new T(); works just as
fine.

>> another major concerned abt using auto_ptr is
>>
>> after the memory allocation is done tht is lets say
>>
>> int main ()
>> {
>> auto_ptr<T>p = (new T()) ;
>> func(p.get()); //
>> return ( EXIT_SUCESS);
>> }
>>
>> void func(T *output)
>> {
>> // some code
>> }
>>
>> do u see any problem with uisng an auto pointer like above i.e passing
>> as an argument in a function call .

No problem at all, but you might want to consider using a shared pointer
and pass that instead of using get(). Or pass a reference to the auto ptr.

>> Is there any memory Leak ?

No, but there is always the risk that func() will somehow save the
pointer you pass in and someone else will later try to access it.

>> I think the auto of auto ptr is the best way ..
>> Also in the code the malloc is done like
>>
>> T *p = (T *)malloc (sizeof(T)*(n+1));

I'm not sure how it is in C++, but in C you do not have to cast the
result of malloc.

>> so using new for above is like
>>
>> T *p = (T *)new char [sizeof(T)*(n+1)];

T* p = new T[n+1];

--
Erik Wikström

James Kanze

12/7/2008 9:40:00 AM

0

On Dec 6, 4:09 pm, Ami <Amit.Bas...@gmail.com> wrote:

> I have been working on C++  code optimization to minimize the
> memory leaks and better performance on HP-UX with aCC
>  I have the following example to share with you

> I have a structure  SYS_LC_DETAILS_CDA  for which I have
> allocated  a memory using malloc  and then memset and then
> calling a function to assign values to the structure elements
> as  below
>   SYS_LC_DETAILS_CDA *p_str_lc_details = (SYS_LC_DETAILS_CDA *)malloc
> (sizeof(SYS_LC_DETAILS_CDA));
>  memset(p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));
> conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);
> and calling free()

> in another example im using a new operator as below
>  SYS_LC_DETAILS_CDA *p_str_lc_details = new  SYS_LC_DETAILS_CDA ;
>  memset(p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));
> conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);
> then delete

Why the memset? Why not a constructor?

Even in C, memset is NOT the preferred solution; it's much
better to define a static instance of the struct, and assign it.

> in a 3rd way I do as below
> SYS_LC_DETAILS_CDA p_str_lc_details;
>  memset(&p_str_lc_details,'\0',sizeof(SYS_LC_DETAILS_CDA));
> in above case I dont have to deallocate any...

The semantics are not the same. If the value has automatic
lifetime, using dynamic allocation is an abberation which should
be avoided at all costs.

> in a 4th way I am using an auto_ptr as below
> auto_ptr<SYS_LC_DETAILS_CDA>p_str_lc_details = (new
> SYS_LC_DETAILS_CDA) ;
> and then passing the pointer variable as
> conObj.CopyToDceSYS_LC_DETAILS_CDA(p_str_lc_details,pStrLcDetails);

> Which is the better way of allocating . auto_ptr score  well
> above the rest as the object gets destroyed as soon as it goes
> out of scope ...

> So which is the best way to minimize the meamory leaks ?

Automatic variables for automatic lifetime.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

12/7/2008 9:48:00 AM

0

On Dec 7, 10:34 am, Erik Wikström <Erik-wikst...@telia.com> wrote:
> On 2008-12-06 23:36, blargg wrote:

> > Ami wrote:
> > My god that is so hard to read. Look at the difference a
> > couple of find-and-replaces and some indention do:

> And it lets us find some things to improve upon.

> >> I have few qustions
> >> Consider the allocation

> >>   T p(T());

>   T p(); will do just as well.

Not at local scope (which IIRC was the case). At local scope,
that declares a function.

> >> T() in above would do default initialization right
> >> then I can safely avoid the use of C style memset..
> >> and then nevere have to de allocate the same.

> >> As far as auto_ptr is concrned , do I again need to
> >> initialize to T () as shown below

> >>   auto_ptr<T>p = (new T()) ;

> No need to use () around the new, auto_ptr<T>p = new T();
> works just as fine.

It shouldn't. At least according to C++98. (I don't have a
copy of the C++03 standard here.) There's no assignment
operator of auto_ptr which takes a T*, and there's no implicit
conversion.

> >> another major concerned abt using auto_ptr is

> >> after the memory allocation is done tht is lets say

> >>   int main ()
> >>   {
> >>       auto_ptr<T>p = (new T()) ;
> >>       func(p.get()); //
> >>       return ( EXIT_SUCESS);
> >>   }

> >>   void func(T *output)
> >>   {
> >>     // some code
> >>   }

> >> do u see any problem with uisng an auto pointer like above
> >> i.e passing as an argument in a function call .

> No problem at all, but you might want to consider using a
> shared pointer and pass that instead of using get(). Or pass a
> reference to the auto ptr.

Or pass a reference to the object, using *p in the calling
function. (Unless the called function is capable of handling a
null pointer, this is the preferred solution.)

> >> Is there any memory Leak ?

> No, but there is always the risk that func() will somehow save
> the pointer you pass in and someone else will later try to
> access it.

> >> I think the auto of auto ptr is the best way ..
> >> Also in the code the malloc is done like

> >>   T *p = (T *)malloc (sizeof(T)*(n+1));

> I'm not sure how it is in C++, but in C you do not have to
> cast the result of malloc.

In C++, you do.

> >> so using new for above is like

> >>   T *p = (T *)new char [sizeof(T)*(n+1)];

>   T* p = new T[n+1];

Just a reminder, too. You can't use std::auto_ptr with array
new. In C++, the preferred solution for this would be:

std::vector< char > obj( sizeof(T)*(n+1) ) ;

(Except that I suspect that what he wants is:

std::vector< T > obj( n + 1 ) ;

..)

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Ami

12/7/2008 12:32:00 PM

0

On Dec 7, 2:48 pm, James Kanze <james.ka...@gmail.com> wrote:
> On Dec 7, 10:34 am, Erik Wikström <Erik-wikst...@telia.com> wrote:
>
> > On 2008-12-06 23:36, blargg wrote:
> > > Ami wrote:
> > > My god that is so hard to read. Look at the difference a
> > > couple of find-and-replaces and some indention do:
> > And it lets us find some things to improve upon.
> > >> I have few qustions
> > >> Consider the allocation
> > >>   T p(T());
> >   T p(); will do just as well.
>
> Not at local scope (which IIRC was the case).  At local scope,
> that declares a function.
>
> > >> T() in above would do default initialization right
> > >> then I can safely avoid the use of C style memset..
> > >> and then nevere have to de allocate the same.
> > >> As far as auto_ptr is concrned , do I again need to
> > >> initialize to T () as shown below
> > >>   auto_ptr<T>p = (new T()) ;
> > No need to use () around the new, auto_ptr<T>p = new T();
> > works just as fine.
>
> It shouldn't.  At least according to C++98.  (I don't have a
> copy of the C++03 standard here.)  There's no assignment
> operator of auto_ptr which takes a T*, and there's no implicit
> conversion.
>
>
>
>
>
> > >> another major concerned abt using auto_ptr is
> > >> after the memory allocation is done tht is lets say
> > >>   int main ()
> > >>   {
> > >>       auto_ptr<T>p = (new T()) ;
> > >>       func(p.get()); //
> > >>       return ( EXIT_SUCESS);
> > >>   }
> > >>   void func(T *output)
> > >>   {
> > >>     // some code
> > >>   }
> > >> do u see any problem with uisng an auto pointer like above
> > >> i.e passing as an argument in a function call .
> > No problem at all, but you might want to consider using a
> > shared pointer and pass that instead of using get(). Or pass a
> > reference to the auto ptr.
>
> Or pass a reference to the object, using *p in the calling
> function.  (Unless the called function is capable of handling a
> null pointer, this is the preferred solution.)
>
> > >> Is there any memory Leak ?
> > No, but there is always the risk that func() will somehow save
> > the pointer you pass in and someone else will later try to
> > access it.
> > >> I think the auto of auto ptr is the best way ..
> > >> Also in the code the malloc is done like
> > >>   T *p = (T *)malloc (sizeof(T)*(n+1));
> > I'm not sure how it is in C++, but in C you do not have to
> > cast the result of malloc.
>
> In C++, you do.
>
> > >> so using new for above is like
> > >>   T *p = (T *)new char [sizeof(T)*(n+1)];
> >   T* p = new T[n+1];
>
> Just a reminder, too.  You can't use std::auto_ptr with array
> new.  In C++, the preferred solution for this would be:
>
>     std::vector< char > obj( sizeof(T)*(n+1) ) ;
>
> (Except that I suspect that what he wants is:
>
>     std::vector< T > obj( n + 1 ) ;
>
> .)
>
> --
> James Kanze (GABI Software)             email:james.ka...@gmail.com
> Conseils en informatique orientée objet/
>                    Beratung in objektorientierter Datenverarbeitung
> 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34- Hide quoted text -
>
> - Show quoted text -

Thanks James and Eric for the explanation.. I have few questions
Eric you mention about passing a reference to the auto ptr for example
in the sample code , I have got now
int main ()
{
auto_ptr<T>p = (new T()) ;
func(&(p.get())); // Im passing a reference to the auto _ptr
p.release(); // Would free up
return ( EXIT_SUCESS);
}
void func(T *output)
{
output->do_Something();
}

Now if there is any exception gets thrown in the func()
what would be the behaviour of auto _ptr ??

Also in a function call please correct me if I am wrong
I can use * as func(*(p.get()));
correct ?

James .. My another question is
for allocating a memory to an array of structures
You mentioned about using vector like below
int main ()
{
std::vector< T > obj( n + 1 ) ;
func(obj);
return(EXIT_SUCCESS);
}
void func(&obj)
{
obj->do_Something();
}

if any exception is thrown in func() .. what will the end result ?

Many Thanks for your time

Ami

12/7/2008 2:47:00 PM

0

On Dec 7, 5:32 pm, Ami <Amit.Bas...@gmail.com> wrote:
> On Dec 7, 2:48 pm, James Kanze <james.ka...@gmail.com> wrote:
>
>
>
>
>
> > On Dec 7, 10:34 am, Erik Wikström <Erik-wikst...@telia.com> wrote:
>
> > > On 2008-12-06 23:36, blargg wrote:
> > > > Ami wrote:
> > > > My god that is so hard to read. Look at the difference a
> > > > couple of find-and-replaces and some indention do:
> > > And it lets us find some things to improve upon.
> > > >> I have few qustions
> > > >> Consider the allocation
> > > >>   T p(T());
> > >   T p(); will do just as well.
>
> > Not at local scope (which IIRC was the case).  At local scope,
> > that declares a function.
>
> > > >> T() in above would do default initialization right
> > > >> then I can safely avoid the use of C style memset..
> > > >> and then nevere have to de allocate the same.
> > > >> As far as auto_ptr is concrned , do I again need to
> > > >> initialize to T () as shown below
> > > >>   auto_ptr<T>p = (new T()) ;
> > > No need to use () around the new, auto_ptr<T>p = new T();
> > > works just as fine.
>
> > It shouldn't.  At least according to C++98.  (I don't have a
> > copy of the C++03 standard here.)  There's no assignment
> > operator of auto_ptr which takes a T*, and there's no implicit
> > conversion.
>
> > > >> another major concerned abt using auto_ptr is
> > > >> after the memory allocation is done tht is lets say
> > > >>   int main ()
> > > >>   {
> > > >>       auto_ptr<T>p = (new T()) ;
> > > >>       func(p.get()); //
> > > >>       return ( EXIT_SUCESS);
> > > >>   }
> > > >>   void func(T *output)
> > > >>   {
> > > >>     // some code
> > > >>   }
> > > >> do u see any problem with uisng an auto pointer like above
> > > >> i.e passing as an argument in a function call .
> > > No problem at all, but you might want to consider using a
> > > shared pointer and pass that instead of using get(). Or pass a
> > > reference to the auto ptr.
>
> > Or pass a reference to the object, using *p in the calling
> > function.  (Unless the called function is capable of handling a
> > null pointer, this is the preferred solution.)
>
> > > >> Is there any memory Leak ?
> > > No, but there is always the risk that func() will somehow save
> > > the pointer you pass in and someone else will later try to
> > > access it.
> > > >> I think the auto of auto ptr is the best way ..
> > > >> Also in the code the malloc is done like
> > > >>   T *p = (T *)malloc (sizeof(T)*(n+1));
> > > I'm not sure how it is in C++, but in C you do not have to
> > > cast the result of malloc.
>
> > In C++, you do.
>
> > > >> so using new for above is like
> > > >>   T *p = (T *)new char [sizeof(T)*(n+1)];
> > >   T* p = new T[n+1];
>
> > Just a reminder, too.  You can't use std::auto_ptr with array
> > new.  In C++, the preferred solution for this would be:
>
> >     std::vector< char > obj( sizeof(T)*(n+1) ) ;
>
> > (Except that I suspect that what he wants is:
>
> >     std::vector< T > obj( n + 1 ) ;
>
> > .)
>
> > --
> > James Kanze (GABI Software)             email:james.ka...@gmail.com
> > Conseils en informatique orientée objet/
> >                    Beratung in objektorientierter Datenverarbeitung
> > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34- Hide quoted text -
>
> > - Show quoted text -
>
> Thanks James and Eric for the explanation.. I have few questions
> Eric you mention about passing a reference to the auto ptr for example
> in the sample code , I have got now
> int main ()
>    {
>        auto_ptr<T>p = (new T()) ;
>        func(&(p.get())); // Im passing a reference to the auto _ptr
>        p.release(); // Would free up
>        return ( EXIT_SUCESS);
>    }
>    void func(T *output)
>    {
>      output->do_Something();
>    }
>
> Now if there is any exception gets thrown in the func()
> what would be the behaviour of auto _ptr ??
>
> Also in a function call please correct me if I am wrong
> I can use * as  func(*(p.get()));
> correct ?
>
> James .. My another question is
> for allocating a memory to an array of structures
> You mentioned about using vector like below
> int main ()
> {
> std::vector< T > obj( n + 1 ) ;
> func(obj);
> return(EXIT_SUCCESS);}
>
> void func(&obj)
> {
>   obj->do_Something();
>
> }
>
> if any exception is thrown in func() .. what will the end result ?
>
> Many Thanks for your time- Hide quoted text -
>
> - Show quoted text -

This is what I have now .. to overcome the flaw of passing by
value ...
Now I have
int main ()
{
auto_ptr<T>p = (new T()) ;
func(p); // appending get() wont work in a function call
p.release();
return ( EXIT_SUCESS);
}
void func(const auto_ptr<T> &output)
{
output->do_Something();
}

works just fine..
Can you please let me know if this is the best way of passing auto_ptr
by reference and avoiding any leaks ?
also why get() doesnt work in a function call func(p.get()) // throws
error

Many Thanks

James Kanze

12/8/2008 9:29:00 AM

0

On Dec 7, 1:32 pm, Ami <Amit.Bas...@gmail.com> wrote:
> On Dec 7, 2:48 pm, James Kanze <james.ka...@gmail.com> wrote:
[...]
> Thanks James and Eric for the explanation.. I have few
> questions Eric you mention about passing a reference to the
> auto ptr for example in the sample code , I have got now
> int main ()
> {
> auto_ptr<T>p = (new T()) ;
> func(&(p.get())); // Im passing a reference to the auto _ptr

That particular line shouldn't compile. p.get() returns a
temporary with pointer type, and the address of operator isn't
legal on temporarires. If it were legal, of course, the results
would have type T**.

(Technically---and you probably should learn the technical
vocabulary---the return value of a function is an rvalue, and
the built-in unary & operator requires an lvalue.)

> p.release(); // Would free up

No. This will release ownership of the pointer from the
auto_ptr, meaning that it is up to you to delete it. One
frequent use of auto_ptr is when creating objects with arbitrary
lifetimes which will later be managed by some special type (a
transation, for example), or by the object itself (which
registers somewhere for events). In such cases, it is usual to
create the object in an auto_ptr, and then call release when the
final management method has taken over, allowing auto_ptr to
manage the object until then.

It's the destructor of auto_ptr which deletes the object, but
only if you haven't called release.

> return ( EXIT_SUCESS);
> }
> void func(T *output)
> {
> output->do_Something();
> }

> Now if there is any exception gets thrown in the func()
> what would be the behaviour of auto_ptr ??

If the exception propagates beyond the scope of the auto_ptr,
it's destructor will be called, and the object will be deleted.

> Also in a function call please correct me if I am wrong I can
> use * as func(*(p.get())); correct ?

If the function takes a reference, yes, but it's very
unidiomatic. What's wrong with simply *p? (Unless the function
needs to be able to take a null pointer (e.g. for an optional
argument), I'd declare it to take a reference.)

> James .. My another question is
> for allocating a memory to an array of structures
> You mentioned about using vector like below
> int main ()
> {
> std::vector< T > obj( n + 1 ) ;
> func(obj);
> return(EXIT_SUCCESS);}

> void func(&obj)
> {
> obj->do_Something();
> }

> if any exception is thrown in func() .. what will the end result ?

If the exception is not caught earlier, the destructor of
std::vector<T> will be called, which will call the destructor of
all of the elements in the vector, and free up any memory the
vector uses.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

12/8/2008 9:33:00 AM

0

On Dec 7, 3:46 pm, Ami <Amit.Bas...@gmail.com> wrote:
> On Dec 7, 5:32 pm, Ami <Amit.Bas...@gmail.com> wrote:

> This is what I have now .. to overcome the flaw of passing by
> value ...

What's the "flaw" of passing by value? If your types have value
semantics, it's usually what you want.

> Now I have
> int main ()
> {
> auto_ptr<T>p = (new T()) ;
> func(p); // appending get() wont work in a function call
> p.release();
> return ( EXIT_SUCESS);
> }
> void func(const auto_ptr<T> &output)
> {
> output->do_Something();
> }

> works just fine..
> Can you please let me know if this is the best way of passing
> auto_ptr by reference and avoiding any leaks ?

In general, I don't like passing references to auto_ptr. Either
the called function is going to take over ownership, and passing
the auto_ptr by value would seem to be indicated, or it's not,
and either derferencing the auto_ptr to pass by reference, or
calling get to pass by pointer, would seem more appropriate.

> also why get() doesnt work in a function call func(p.get()) //
> throws error

What is the signature of func? If func takes a T* (or a T
const*), then p.get() should work.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34