gpt4 book ai didi

c++ - 如果 new 失败,是否需要检查指针有效性?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:16:23 27 4
gpt4 key购买 nike

正如标题所说,我知道 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 运算符,并且没有使用 newnothrow 版本:

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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com