正如标题所说,我知道new会抛出一个可以捕获的异常,但是指针究竟发生了什么?它变成了NULL?我在SO上检查了一些答案,但没有人解释.检查下面的例子,指针保持在堆上?请提供有关此模式的完整信息
#include <windows.h>
#include <cstdlib>
#include <iostream>
using namespace std;
enum eReadMode
{
// READ_ONLY,
READ_WRITE,
// CREATE_FILE,
// CREATE_WRITE_FILE,
};
class CFileStatic
{
private:
FILE *m_File;
public:
CFileStatic( LPCTSTR szFileName, eReadMode eMode );
virtual ~CFileStatic() {};
bool IsValidFile() const { return( m_File != NULL ); };
void PrintFile( unsigned int uLine = 0 );
};
CFileStatic::CFileStatic( LPCTSTR szFileName, eReadMode eMode )
{
if( szFileName )
{
if( eMode == READ_WRITE )
m_File = fopen( szFileName, "r+" );
else
printf( "Valid usage of: READ_WRITE only" );
}
else
m_File = NULL;
}
void CFileStatic::PrintFile( unsigned int uLine )
{
static unsigned uFindNumber;
if( uLine == 0 )
{
char szBuffer[1024];
while( fgets( szBuffer, 1024, m_File ) )
{
std::cout << szBuffer;
}
}
else
{
char szBuffer[1024];
while( fgets( szBuffer, 1024, m_File ) )
{
uFindNumber++;
if( uFindNumber == uLine )
{
std::cout << szBuffer;
}
}
}
}
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 );
if( pFile->IsValidFile() )
{
pFile->PrintFile(2);
}
CFileStatic *pConsoleCpp = new CFileStatic( "Console.cpp", READ_WRITE );
if( pConsoleCpp->IsValidFile() )
{
pConsoleCpp->PrintFile();
}
system("pause>nul");
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
假设您使用的是默认全局new
运算符,并且未使用以下nothrow
版本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 );
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
没有"后来".在此代码中,如果new
失败,它将抛出std::bad_alloc
异常,您的程序将立即终止.
现在,如果您要尝试处理这种情况,则需要捕获该异常.也许是这样的:
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;
}
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
pFile
存在于try
块所包含的范围内,因此不再存在.搬出一个级别:
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
Run Code Online (Sandbox Code Playgroud)
pFile
永远不会被修改,所以价值不变.
关于delete
指针的问题.标准说(C++ 03 5.3.5/2):
[...]如果delete的操作数的值是空指针,则操作无效.
您不必删除NULL指针,因为没有任何内容delete
,但这样做无效.你可以安全地做到这一点:
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
Run Code Online (Sandbox Code Playgroud)
请注意,执行此操作时,初始化pFile
为空指针尤其重要,就像我在这里所做的那样.如果你不这样做:
CFileStatic* pFile; // NO INIT
/* ... */
delete pFile; // if new threw, this is undefined behavior
Run Code Online (Sandbox Code Playgroud)
pFile
仍然是垃圾指针.它不是空指针,因此delete
会尝试删除它,从而导致未定义的行为.