catch exception

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • junw2000@gmail.com

    catch exception

    class A
    {
    public:
    A()
    {
    try
    {
    p = new int;
    //Other lines that may throw exception.
    }
    catch(...)
    {
    delete p;
    }

    private:
    int *p;
    };

    In the above code, catch the exception in A's constructor to delete p.
    Is it OK? Is there a better way to delete p?

    Thanks.

    Jack
  • Andre Kostur

    #2
    Re: catch exception

    junw2000@gmail. com wrote in news:33ee848b-a4f5-44e9-86dd-
    9bff7200191d@v2 6g2000prm.googl egroups.com:
    class A
    {
    public:
    A()
    {
    try
    {
    p = new int;
    //Other lines that may throw exception.
    }
    catch(...)
    {
    delete p;
    }
    >
    private:
    int *p;
    };
    >
    In the above code, catch the exception in A's constructor to delete p.
    Is it OK? Is there a better way to delete p?
    It will work... what would be better is to use some sort of smart pointer
    class, such as std::auto_ptr. Assuming you need the dynamic allocation in
    the first place (In this simple example, it makes no sense to make p
    dynamic at all...)

    Example:


    class A
    {
    public:
    A() : p(new int)
    {
    // Other potentially throwing code
    }

    private:
    std::auto_ptr<i ntp;
    };

    Comment

    • red floyd

      #3
      Re: catch exception

      On Aug 22, 2:15 pm, junw2...@gmail. com wrote:
      class A
      {
      public:
          A()
          {
               try
               {
                     p = new int;
                     //Other lines that may throw exception.
               }
               catch(...)
               {
                     delete p;
               }
      >
      private:
           int *p;
      >
      };
      >
      In the above code, catch the exception in A's constructor to delete p.
      Is it OK? Is there a better way to delete p?
      >
      Yes it's OK (modulo the missing closing brace), but better is:

      class A
      {
      public:
      A() : p(new int(0))
      {
      // do other stuff which may throw
      }

      private:
      some_smart_poin ter_type<intp;

      };

      Now if that stuff throws, the smart pointer for p will be destroyed,
      which will delete p.
      Pick your smart pointer -- see boost and tr1. Or, if you know this
      object won't be getting copied, or you have a deep copy constructor,
      you could use std::auto_ptr



      Comment

      • gpderetta

        #4
        Re: catch exception

        On Aug 22, 11:15 pm, junw2...@gmail. com wrote:
        class A
        {
        public:
        A()
        {
        try
        {
        p = new int;
        //Other lines that may throw exception.
        }
        catch(...)
        {
        delete p;
        }
        >
        private:
        int *p;
        >
        };
        >
        If 'new int' throws, you'll be deleting an uninitialized pointer which
        is UB.
        It is safer and simpler to use a smart pointer.

        HTH,

        --
        gpd

        Comment

        • Juha Nieminen

          #5
          Re: catch exception

          Andre Kostur wrote:
          junw2000@gmail. com wrote in news:33ee848b-a4f5-44e9-86dd-
          9bff7200191d@v2 6g2000prm.googl egroups.com:
          >
          >class A
          >{
          >public:
          > A()
          > {
          > try
          > {
          > p = new int;
          > //Other lines that may throw exception.
          > }
          > catch(...)
          > {
          > delete p;
          > }
          >>
          >private:
          > int *p;
          >};
          >>
          >In the above code, catch the exception in A's constructor to delete p.
          >Is it OK? Is there a better way to delete p?
          >
          It will work...
          Really? What will be the value of p if 'new' throws?

          Wouldn't it be better like this:

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

          Comment

          • Joe Greer

            #6
            Re: catch exception

            Juha Nieminen <nospam@thanks. invalidwrote in news:t5Qrk.51$M E2.22
            @read4.inet.fi:
            >
            Really? What will be the value of p if 'new' throws?
            >
            Wouldn't it be better like this:
            >
            A(): p(0)
            {
            try
            {
            p = new int;
            }
            catch(...)
            {
            delete p;
            }
            }
            >
            It depends upon what you are after, In the previous case, if new
            throws, p is never assigned a value and A is never constructed. If all
            of your resources are wrapped in RAII classes (such as auto_ptr), then
            anything constructed prior to the new throwing will be cleaned up as the
            exception leaves A's constructor. This is all done for you. The code
            you provided really doesn't do anything. If the new throws, then p
            won't need deleted. If the new works, then it won't be deleted. If you
            didn't want the new to prevent the construction of A, then you could do
            something like:

            A()
            {
            try
            {
            std::auto_ptr<i ntp(new int);
            //do stuff with p
            // p gets automatically deleted as it leaves this scope.
            } catch(...)
            { // don't really care if the above worked or not
            }

            // do other stuff
            }

            -or-

            A()
            {
            try
            {
            p.reset(new int);
            //do stuff with p
            // p gets automatically deleted when A gets deleted.
            } catch(...)
            { // don't really care if the above worked or not
            }

            // do other stuff
            std::auto_ptr<i ntp;
            }


            Both of these would prevent the allocation of p from preventing the
            construction of A (though if you are really that low on memory, do you
            really want to carry on?) and will automatically handle the deletion of
            the object when A is destroyed.

            Generally speaking (meaning there are always special cases) I think
            Andre's solution is the cleanest for most uses.


            joe

            Comment

            • junw2000@gmail.com

              #7
              Re: catch exception

              On Aug 22, 2:57 pm, gpderetta <gpdere...@gmai l.comwrote:
              On Aug 22, 11:15 pm, junw2...@gmail. com wrote:
              >
              >
              >
              class A
              {
              public:
                  A()
                  {
                       try
                       {
                             p = new int;
                             //Other lines that may throw exception.
                       }
                       catch(...)
                       {
                             delete p;
                       }
              >
              private:
                   int *p;
              >
              };
              >
              If 'new int' throws, you'll be deleting an uninitialized pointer which
              is UB.
              It is safer and simpler to use a smart pointer.
              >
              HTH,
              >
              --
              gpd
              In fact, smart pointer will also delete p. Theoretically, they are the
              same, rigth?

              Jack

              Comment

              • gpderetta

                #8
                Re: catch exception

                On Aug 24, 2:24 am, junw2...@gmail. com wrote:
                On Aug 22, 2:57 pm, gpderetta <gpdere...@gmai l.comwrote:
                >
                On Aug 22, 11:15 pm, junw2...@gmail. com wrote:
                >
                class A
                {
                public:
                A()
                {
                try
                {
                p = new int;
                //Other lines that may throw exception.
                }
                catch(...)
                {
                delete p;
                }
                >
                private:
                int *p;
                >
                };
                >
                If 'new int' throws, you'll be deleting an uninitialized pointer which
                is UB.
                It is safer and simpler to use a smart pointer.
                >
                >
                In fact, smart pointer will also delete p.
                The smart pointer will not delete 'p', 'p' will be the smart pointer :

                struct A() {

                A() p(new int) { /* do something with p */ }
                private:
                std::auto_ptr<i ntp;
                };
                Theoretically, they are the
                same, rigth?
                >
                Wrong. If 'new int' trows, the smart pointer won't have been
                constructed yet, so its destructor won't be called.

                OTOH, if you instead reset p to 'new int' in the body of the
                constructor, the smart pointer will have been default constructed. If
                'new int' throws, p destructor will be called, but destroying a
                default constructed smart pointer will not lead to UB (well, at least
                for any reasonable smart pointer).

                In general, the less you use try/catch, the easier is not to make
                mistakes. RAII is your friend.

                HTH,

                --
                gpd

                Comment

                Working...