Is it required to check a pointer validity if new fails?

前端 未结 4 862
轮回少年
轮回少年 2021-01-15 21:29

As title says, i know that new throws an exception which can be caught, but what exactly happens to the pointer? it turns NULL? I checked some answers on SO but none explain

相关标签:
4条回答
  • 2021-01-15 22:14

    If an exception is thrown, then the pointer will not be assigned a new value. If your pointer is scoped inside of the try block where you do the allocation, or is not scoped in any try block, then the exception will cause the scope to change such that you can't access the pointer any more. Consequently, there's no need to test the pointer.

    If, on the other hand, the pointer is declared in a way where it persists after the allocation fails, then you would need to check the value. For example:

    T* ptr = NULL;
    try {
        ptr = new T();
    } catch (std::bad_alloc& ) {
        /* ... handle error */
    }
    // Have to test ptr here, since it could still be NULL.
    

    Hope this helps!

    0 讨论(0)
  • 2021-01-15 22:16

    When an exception is thrown out of a function the function does not complete and does not return anything, at the same time control flow jumps to the exception handler and even if the function returned, the assignment to the receiving pointer would not be executed.

    The same goes for the throwing version of new, if it throws, then the pointer would maintain the same value it had before the expression, which might be NULL or any other value.

    On the other hand, if you use new (std::nothrow) X; then the call to new will not throw, and failure will be indicated by a NULL value being returned (and assumingly assigned to a pointer)

    0 讨论(0)
  • 2021-01-15 22:20

    Assuming you are using the default global new operator, and have not used the nothrow version of new:

    int main( int argc, char *argv[] )
    {
      //if new fails, what 'pFile' turns out to be? and do I need to delete
      //it later?
      CFileStatic *pFile = new CFileStatic( "Console.h", READ_WRITE );
      /* ... */
    }
    

    There is no "later". In this code, if new fails, it will throw an std::bad_alloc exception, and your program will terminate immediately.

    Now, if you were to try to handle this situation, you would need to catch that exception. Perhaps like this:

    int main( int argc, char *argv[] )
    {
      //if new fails, what 'pFile' turns out to be? and do I need to delete
      //it later?
      try
      {
        CFileStatic *pFile = new CFileStatic( "Console.h", READ_WRITE );
      }
      catch( const std::bad_alloc& ex )
      {
        cout << "whoops! out of memory." << ex.what() <<  endl;
      }
      /* ... */
    }
    

    pFile exists within the scope enclosed by the try block, so it no longer exists. Moving out one level:

      CFileStatic * pFile = 0;
      try
      {
        pFile = new CFileStatic( "Console.h", READ_WRITE );
      }
      catch( const std::bad_alloc& ex )
      {
        cout << "whoops! out of memory." << ex.what() <<  endl;
      }
    
      // pFile is still 0
    

    pFile is never modified, so the value is unchanged.


    Regarding the question of deleteing the pointer. The Standard says (C++03 5.3.5/2):

    [...] if the value of the operand of delete is the null pointer the operation has no effect.

    You do not have to delete a NULL pointer, because there is nothing to delete, but doing so will have no effect. You could safely do this:

    CFileStatic * pFile = 0;
    try
    {
      pFile = new CFileStatic( "Console.h", READ_WRITE );
    }
    catch( const std::bad_alloc& ex )
    {
      cout << "whoops! out of memory." << ex.what() <<  endl;
    }
    
    delete pFile;  // regardless of the success of new, this is OK
    

    Note that when doing this, it is especially important that you initialize pFile to the null pointer, as I've done here. If you don't:

    CFileStatic* pFile; // NO INIT
    /* ... */
    delete pFile; // if new threw, this is undefined behavior
    

    pFile will still be a garbage pointer. It's not the null pointer, so delete will try to delete it, resulting in Undefined Behavior.

    0 讨论(0)
  • 2021-01-15 22:29

    If new fails it throws a std::bad_alloc exception, unless you use the nothrow version. This means that the value of the variable to store the returned pointer will be unchanged.

    If you catch the exception the value of pFile remains uninitialized, otherwise your application terminates (as main is exited)

    0 讨论(0)
提交回复
热议问题