正如标题所说,我知道 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;
}
最佳答案
假设您正在使用默认的全局 new
运算符,并且没有使用 new
的 nothrow
版本:
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 );
/* ... */
}
没有“后来”。在这段代码中,如果 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;
}
/* ... */
}
pFile
存在于 try
block 所包含的范围内,因此它不再存在。移出一层:
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
从未被修改,因此值不变。
关于delete
指针的问题。标准说 (C++03 5.3.5/2):
[...] if the value of the operand of delete is the null pointer the operation has no effect.
您不必删除 NULL 指针,因为没有什么可删除
,但这样做不会有任何效果。你可以安全地这样做:
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
请注意,执行此操作时,将 pFile
初始化为空指针尤为重要,正如我在此处所做的那样。如果你不这样做:
CFileStatic* pFile; // NO INIT
/* ... */
delete pFile; // if new threw, this is undefined behavior
pFile
仍然是垃圾指针。它不是空指针,因此 delete
将尝试删除它,从而导致未定义的行为。
关于c++ - 如果 new 失败,是否需要检查指针有效性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11089986/