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

前端 未结 4 882
轮回少年
轮回少年 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: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.

提交回复
热议问题