-5

Why can't I catch this exception?

My (client) code:

Eigen::MatrixXd FFs ;
try
{
  FFs.resize( NUMPATCHES, NUMPATCHES ) ;
}
catch( int e )
{
  error( "Not enough memory :(" ) ;
  return ;
}

The Eigen code that throws the exception is a few levels down..

    EIGEN_STRONG_INLINE void resize(Index rows, Index cols)
    {
        internal::check_rows_cols_for_overflow(rows, cols);
        m_storage.resize(rows*cols, rows, cols);
    }

Which calls

    void resize(DenseIndex size, DenseIndex rows, DenseIndex cols)
    {
      if(size != m_rows*m_cols)
      {
        internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols);
        if (size)
          m_data = internal::conditional_aligned_new_auto(size);
        else
          m_data = 0;
        EIGEN_INTERNAL_DENSE_STORAGE_CTOR_PLUGIN
      }
      m_rows = rows;
      m_cols = cols;
    }

The bolded lines are the ones that get hit before the line:

throw std::bad_alloc();

gets hit, which happens somewhere inside the internal::conditional_aligned_delete_auto(m_data, m_rows*m_cols); function call.

Why can't I catch this exception from my client code? Is it because the Eigen library didn't mark the resize function with throws? How can I make this code using the Eigen library recover from this malloc type error smoothly?

bobobobo
  • 64,917
  • 62
  • 258
  • 363

4 Answers4

12

You have to catch with the correct exception type. Use:

catch( std::exception &e )

instead of:

catch( int e )
finalman
  • 774
  • 5
  • 14
8
catch( std::bad_alloc& e) {
}

should help

Stefan
  • 1,091
  • 7
  • 10
6

You are catching an exception of type int, while the actual exception being thrown is of type std::bad_alloc().

catch (std::bad_alloc& e)
{
    exit(1); // or some other appropriate behavior
}

is probably what you want.

Andy Finkenstadt
  • 3,547
  • 1
  • 21
  • 25
2

The problem was the exception being thrown by resize() was std::exception. However, the code in the question explicitly tries to capture exceptions of type int. This won't work and the catch block will be passed.

One way to fix this is by using a general "catch all" block:

try
{
  FFs.resize( NUMPATCHES, NUMPATCHES ) ;
}
catch(...) // catch all exceptions, no type declaration required
{
  error( "Not enough memory :(" ) ;
  return ;
}

The ellipses in the catch(...) statement mean you don't have to resolve exception type. All exceptions will be caught, regardless of type.

However this appears to be not recommended. This may be analogous to the generic catch( Exception e ) statements in Java and C#, which is frowned upon in those languages for reasons stated here.

Community
  • 1
  • 1
bobobobo
  • 64,917
  • 62
  • 258
  • 363
  • 1
    catch(...) will also catch all sorts of exceptions that are not normally thrown as a std::exception, like floating point exceptions, division by zero, page faults, etc. It can be very useful if you are calling code you don't fully trust (for example, a plugin) and you want to keep it from crashing your whole application if it does something nasty. – finalman Aug 01 '12 at 11:15