PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > Challenging GotW 66's moral
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Challenging GotW 66's moral

Réponse
 
LinkBack Outils de la discussion
Vieux 27/12/2007, 06h54   #1
George2
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Challenging GotW 66's moral

Hello everyone,


In GotW #66, one of the moral is the exception handler of constructor
should not do any like resource free task. I do not agree. Here is the
quoated moral and my code to prove this moral will have memory leak.

Anything wrong with my analysis?

http://www.gotw.ca/gotw/066.htm

Moral #1: Constructor function-try-block handlers have only one
purpose -- to translate an exception. (And maybe to do logging or some
other side effects.) They are not useful for any other purpose.


Code:
class A
{
private:

int* p;

public:

A()
try
{
p = new int[10];

// there are some other exceptions here

}
catch (bad_alloc)
{
// do not delete since bad_alloc means memory pointed by p is
not allocated
}
catch (...)
{
// if we do not delete p, there will be memory leak
// at this point, we are conflicting with Gotw 66's moral 1
if (p) delete[] p;
}
}

thanks in advance,
George
  Réponse avec citation
Vieux 27/12/2007, 09h58   #2
Salt_Peter
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Challenging GotW 66's moral

On Dec 27, 1:54 am, George2 <george4acade...@yahoo.com> wrote:
> Hello everyone,
>
> In GotW #66, one of the moral is the exception handler of constructor
> should not do any like resource free task. I do not agree. Here is the
> quoated moral and my code to prove this moral will have memory leak.
>
> Anything wrong with my analysis?
>
> http://www.gotw.ca/gotw/066.htm
>
> Moral #1: Constructor function-try-block handlers have only one
> purpose -- to translate an exception. (And maybe to do logging or some
> other side effects.) They are not useful for any other purpose.
>
> [code]
> class A
> {
> private:
>
> int* p;
>
> public:
>
> A()
> try
> {
> p = new int[10];
>
> // there are some other exceptions here
>
> }
> catch (bad_alloc)
> {
> // do not delete since bad_alloc means memory pointed by p is
> not allocated
> }
> catch (...)
> {
> // if we do not delete p, there will be memory leak
> // at this point, we are conflicting with Gotw 66's moral 1
> if (p) delete[] p;


at this point, p would never be 0 (even if the new allocation in ctor
body was not processed yet).
Pointer p, as is, has either a valid address or garbage in it.
As far as that catch block is concerned, it'll always delete [] p.

So how about:

A() : p(0)
try
{
p = new int[10];
}
catch(...)
{
if (p) delete[] p;
}

have you considered shared_ptr instead of doing decadent new
allocations?
  Réponse avec citation
Vieux 27/12/2007, 12h14   #3
Erik Wikström
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Challenging GotW 66's moral

On 2007-12-27 07:54, George2 wrote:
> Hello everyone,
>
>
> In GotW #66, one of the moral is the exception handler of constructor
> should not do any like resource free task. I do not agree. Here is the
> quoated moral and my code to prove this moral will have memory leak.
>
> Anything wrong with my analysis?
>
> http://www.gotw.ca/gotw/066.htm
>
> Moral #1: Constructor function-try-block handlers have only one
> purpose -- to translate an exception. (And maybe to do logging or some
> other side effects.) They are not useful for any other purpose.
>
>
>
Code:
> class A
> {
> private:
>
> int* p;
>
> public:
>
>     A()
>     try
>     {
>         p = new int[10];
>
>         // there are some other exceptions here
>
>     }
>     catch (bad_alloc)
>     {
>         // do not delete since bad_alloc means memory pointed by p is
> not allocated
>     }
>     catch (...)
>     {
>         // if we do not delete p, there will be memory leak
>         // at this point, we are conflicting with Gotw 66's moral 1
>         if (p) delete[] p;
>     }
> }
>


The advice assumes that you follow other advices, such as using RAII and
writing exception safe code, if you did you would never end up in a
situation where you need to free any memory in a catch-block. One
example of that would be to replace p with a smart-pointer.

--
Erik Wikström
  Réponse avec citation
Vieux 27/12/2007, 17h48   #4
Daniel T.
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Challenging GotW 66's moral

George2 <george4academic@yahoo.com> wrote:

> Hello everyone,
>
>
> In GotW #66, one of the moral is the exception handler of constructor
> should not do any like resource free task. I do not agree. Here is the
> quoated moral and my code to prove this moral will have memory leak.
>
> Anything wrong with my analysis?


Your idea is covered in the article:

"--But wait!" I hear someone interrupting from the middle of the
room. "I don't agree with Moral #1. I can think of another possible
use for constructor function-try-blocks, namely to free resources
allocated in the initializer list or in the constructor body!"

Sorry, nope. After all, remember that once you get into your
constructor try-block's handler, any local variables in the
constructor body are also already out of scope, and you are
guaranteed that no base subobjects or member objects exist any more,
period. You can't even refer to their names.

Maybe the output to the following will :

class B {
public:
B() { cout << "B()\n"; }
~B() { cout << "~B()\n"; }
void foo() { cout << "B::foo()\n"; }
};

class A
{
private:
B b;
public:
A() try: b()
{
throw -1;
}
catch (...)
{
b.foo();
}
};

int main() {
try {
A a;
}
catch ( ... ) { }
}

Note that B::foo() is called *after b's destructor has already been
called.* Thus invoking undefined behavior.

> http://www.gotw.ca/gotw/066.htm
>
> Moral #1: Constructor function-try-block handlers have only one
> purpose -- to translate an exception. (And maybe to do logging or some
> other side effects.) They are not useful for any other purpose.
>
>
>
Code:
> class A
> {
> private:
>
> int* p;
>
> public:
>
>     A()
>     try
>     {
>         p = new int[10];
>
>         // there are some other exceptions here
>
>     }
>     catch (bad_alloc)
>     {
>         // do not delete since bad_alloc means memory pointed by p is
> not allocated
>     }
>     catch (...)
>     {
>         // if we do not delete p, there will be memory leak
>         // at this point, we are conflicting with Gotw 66's moral 1
>         if (p) delete[] p;
Code:
'p' doesn't exist once you get in the catch block. Yes, in your example
it happens to still point to the right place, but there is no guarantee
that this is true. Frankly, I'm surprised the code even compiled.

>     }
> }
> 

>
>
> thanks in advance,
> George

  Réponse avec citation
Vieux 27/12/2007, 17h48   #5
Salt_Peter
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Challenging GotW 66's moral

On Dec 27, 4:58 am, Salt_Peter <pj_h...@yahoo.com> wrote:
> On Dec 27, 1:54 am, George2 <george4acade...@yahoo.com> wrote:
>
>
>
> > Hello everyone,

>
> > In GotW #66, one of the moral is the exception handler of constructor
> > should not do any like resource free task. I do not agree. Here is the
> > quoated moral and my code to prove this moral will have memory leak.

>
> > Anything wrong with my analysis?

>
> >http://www.gotw.ca/gotw/066.htm

>
> > Moral #1: Constructor function-try-block handlers have only one
> > purpose -- to translate an exception. (And maybe to do logging or some
> > other side effects.) They are not useful for any other purpose.

>
> > [code]
> > class A
> > {
> > private:

>
> > int* p;

>
> > public:

>
> > A()
> > try
> > {
> > p = new int[10];

>
> > // there are some other exceptions here

>
> > }
> > catch (bad_alloc)
> > {
> > // do not delete since bad_alloc means memory pointed by p is
> > not allocated
> > }
> > catch (...)
> > {
> > // if we do not delete p, there will be memory leak
> > // at this point, we are conflicting with Gotw 66's moral 1
> > if (p) delete[] p;

>
> at this point, p would never be 0 (even if the new allocation in ctor
> body was not processed yet).
> Pointer p, as is, has either a valid address or garbage in it.
> As far as that catch block is concerned, it'll always delete [] p.
>
> So how about:
>
> A() : p(0)
> try
> {
> p = new int[10];}
>
> catch(...)
> {
> if (p) delete[] p;
>
> }
>
> have you considered shared_ptr instead of doing decadent new
> allocations?



obviously, clarification is required since you can't allocate an array
using boost::shared_ptr.
replace the array with a std:vector or use boost::scoped_array.
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 19h11.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,14150 seconds with 13 queries