Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. try-catch dynamic memory cleanup

try-catch dynamic memory cleanup

Scheduled Pinned Locked Moved C / C++ / MFC
performancehelptutorialquestion
7 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • X Offline
    X Offline
    x87Bliss
    wrote on last edited by
    #1

    I am somewhat familiar with a try-catch block and that it automatically destructs objects on exception. However, I'm curious if it automatically frees dynamically allocated memory from the "new" operator?

    void failfunc()
    {
    throw 1; // obviously not practical, just for example
    }

    void main()
    {
    try
    {
    char *mystr = new char[512]; // something in the try block determines the size needed, so must be allocated in the try block
    failfunc(); // would normally actually do something
    delete [] mystr;
    }
    catch (int ierr)
    {
    //tell user an error occured
    if (mystr != NULL) delete [] mystr; // is this line needed, or will the exception have freed mystr?
    }
    }

    P C N S 4 Replies Last reply
    0
    • X x87Bliss

      I am somewhat familiar with a try-catch block and that it automatically destructs objects on exception. However, I'm curious if it automatically frees dynamically allocated memory from the "new" operator?

      void failfunc()
      {
      throw 1; // obviously not practical, just for example
      }

      void main()
      {
      try
      {
      char *mystr = new char[512]; // something in the try block determines the size needed, so must be allocated in the try block
      failfunc(); // would normally actually do something
      delete [] mystr;
      }
      catch (int ierr)
      {
      //tell user an error occured
      if (mystr != NULL) delete [] mystr; // is this line needed, or will the exception have freed mystr?
      }
      }

      C Offline
      C Offline
      Cedric Moonen
      wrote on last edited by
      #2

      No, you have to free the memory yourself.

      Cédric Moonen Software developer
      Charting control [v1.4] OpenGL game tutorial in C++

      1 Reply Last reply
      0
      • X x87Bliss

        I am somewhat familiar with a try-catch block and that it automatically destructs objects on exception. However, I'm curious if it automatically frees dynamically allocated memory from the "new" operator?

        void failfunc()
        {
        throw 1; // obviously not practical, just for example
        }

        void main()
        {
        try
        {
        char *mystr = new char[512]; // something in the try block determines the size needed, so must be allocated in the try block
        failfunc(); // would normally actually do something
        delete [] mystr;
        }
        catch (int ierr)
        {
        //tell user an error occured
        if (mystr != NULL) delete [] mystr; // is this line needed, or will the exception have freed mystr?
        }
        }

        P Offline
        P Offline
        pallaka
        wrote on last edited by
        #3

        You have allocated memory in a heap by using new. And after that you are executing the next statement which is failing. As i Know you should delete the memory which is created dynamically. So in catch statement the deletion part is must. But if

        failfunc(); // would normally actually do something
        char *mystr = new char[512]; // something in the try block determines the size needed, so must
        be allocated in the try block
        Statement 1.....
        delete [] mystr;

        then as function failed it will not try to execute the next statment so there it will skip the creation of memory .so you need not to delete ....

        1 Reply Last reply
        0
        • X x87Bliss

          I am somewhat familiar with a try-catch block and that it automatically destructs objects on exception. However, I'm curious if it automatically frees dynamically allocated memory from the "new" operator?

          void failfunc()
          {
          throw 1; // obviously not practical, just for example
          }

          void main()
          {
          try
          {
          char *mystr = new char[512]; // something in the try block determines the size needed, so must be allocated in the try block
          failfunc(); // would normally actually do something
          delete [] mystr;
          }
          catch (int ierr)
          {
          //tell user an error occured
          if (mystr != NULL) delete [] mystr; // is this line needed, or will the exception have freed mystr?
          }
          }

          N Offline
          N Offline
          not_in_use
          wrote on last edited by
          #4

          Objects allocated on the heap (i.e. via new) are not freed automatically. Objects allocated on the stack (like MyObject obj;) are freed when they go out of scope (i.e. when the execution leaves the innermost {} that surrounds the declaration) or when an exception is thrown. So in your example, if failfunc() throws an exception other than an integer (which can easily happen when someone changes failfunc() but not main()), you got yourself a memory leak. However, you can use what's called a smart pointer to get the desired behavior. The smart pointer is is a helper class that is allocated on the stack and behaves like a regular pointer, and when an exception is thrown its destructor gets called. In that destructor, it calls delete[] on its pointee. Just google smart pointers. Example (not tested):

          //
          // Smart pointer class for arrays
          //
          template< typename T >
          class ArrayPtr
          {

          public:

          ArrayPtr( T\* pointee )
              : \_pointee( pointee )
          {
          }
          
          inline ~ArrayPtr() {
              if( \_pointee )
                  delete\[\] \_pointee; // Array destruction
          } 
          
          operator T\*() {
              return \_pointee
          }
          
          // ... more needed here. Just google smart pointers.
          // Basically you need operator->, operator\*, but not operator&
          // plus assignment etc.
          

          private:

          T\* \_pointee;
          

          };

          //
          // How to use it in your example
          //
          void failfunc()
          {
          throw 1; // obviously not practical, just for example
          }

          void main()
          {
          try {
          ArrayPtr< char > mystr( new char[512] ); // Freed automatically when mystr goes out of scope or an exception is thrown
          failfunc();
          } catch( int err ) {
          // Tell the user something went wrong
          std::cerr << "Error #" << err << std::endl;
          }
          }

          Or if you don't need to print out an error message:

          template< typename T > class ArrayPtr { /*... see above*/ };

          void failfunc() { /*... see above*/ }

          void main()
          {
          ArrayPtr< char > mystr( new char[512] ); // Freed automatically when mystr goes out of scope or an exception is thrown
          failfunc();
          }

          Note that you cannot use the standard C++ std::auto_ptr for arrays since its destructor only calls delete, not delete[]. This also implies that you need a separate smart pointer type for data allocated with malloc since it must be freed using free, not delete[]

          X 1 Reply Last reply
          0
          • N not_in_use

            Objects allocated on the heap (i.e. via new) are not freed automatically. Objects allocated on the stack (like MyObject obj;) are freed when they go out of scope (i.e. when the execution leaves the innermost {} that surrounds the declaration) or when an exception is thrown. So in your example, if failfunc() throws an exception other than an integer (which can easily happen when someone changes failfunc() but not main()), you got yourself a memory leak. However, you can use what's called a smart pointer to get the desired behavior. The smart pointer is is a helper class that is allocated on the stack and behaves like a regular pointer, and when an exception is thrown its destructor gets called. In that destructor, it calls delete[] on its pointee. Just google smart pointers. Example (not tested):

            //
            // Smart pointer class for arrays
            //
            template< typename T >
            class ArrayPtr
            {

            public:

            ArrayPtr( T\* pointee )
                : \_pointee( pointee )
            {
            }
            
            inline ~ArrayPtr() {
                if( \_pointee )
                    delete\[\] \_pointee; // Array destruction
            } 
            
            operator T\*() {
                return \_pointee
            }
            
            // ... more needed here. Just google smart pointers.
            // Basically you need operator->, operator\*, but not operator&
            // plus assignment etc.
            

            private:

            T\* \_pointee;
            

            };

            //
            // How to use it in your example
            //
            void failfunc()
            {
            throw 1; // obviously not practical, just for example
            }

            void main()
            {
            try {
            ArrayPtr< char > mystr( new char[512] ); // Freed automatically when mystr goes out of scope or an exception is thrown
            failfunc();
            } catch( int err ) {
            // Tell the user something went wrong
            std::cerr << "Error #" << err << std::endl;
            }
            }

            Or if you don't need to print out an error message:

            template< typename T > class ArrayPtr { /*... see above*/ };

            void failfunc() { /*... see above*/ }

            void main()
            {
            ArrayPtr< char > mystr( new char[512] ); // Freed automatically when mystr goes out of scope or an exception is thrown
            failfunc();
            }

            Note that you cannot use the standard C++ std::auto_ptr for arrays since its destructor only calls delete, not delete[]. This also implies that you need a separate smart pointer type for data allocated with malloc since it must be freed using free, not delete[]

            X Offline
            X Offline
            x87Bliss
            wrote on last edited by
            #5

            Thanks very much for the descriptive information. The example code is an excellent solution for my problem. I really appreciate you taking the time to answer that thoroughly.

            N 1 Reply Last reply
            0
            • X x87Bliss

              Thanks very much for the descriptive information. The example code is an excellent solution for my problem. I really appreciate you taking the time to answer that thoroughly.

              N Offline
              N Offline
              not_in_use
              wrote on last edited by
              #6

              Glad I could help :)

              1 Reply Last reply
              0
              • X x87Bliss

                I am somewhat familiar with a try-catch block and that it automatically destructs objects on exception. However, I'm curious if it automatically frees dynamically allocated memory from the "new" operator?

                void failfunc()
                {
                throw 1; // obviously not practical, just for example
                }

                void main()
                {
                try
                {
                char *mystr = new char[512]; // something in the try block determines the size needed, so must be allocated in the try block
                failfunc(); // would normally actually do something
                delete [] mystr;
                }
                catch (int ierr)
                {
                //tell user an error occured
                if (mystr != NULL) delete [] mystr; // is this line needed, or will the exception have freed mystr?
                }
                }

                S Offline
                S Offline
                Stephen Hewitt
                wrote on last edited by
                #7

                You could use something like Boost[^]'s scoped_array[^] to avoid having to free the memory using a catch.

                Steve

                1 Reply Last reply
                0
                Reply
                • Reply as topic
                Log in to reply
                • Oldest to Newest
                • Newest to Oldest
                • Most Votes


                • Login

                • Don't have an account? Register

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • World
                • Users
                • Groups