Joo*_*kia 23 c++ throw new-operator bad-alloc
我有这个代码..
CEngineLayer::CEngineLayer(void)
{
// Incoming creation of layers. Wrapping all of this in a try/catch block is
// not helpful if logging of errors will happen.
logger = new (std::nothrow) CLogger(this);
if(logger == 0)
{
std::bad_alloc exception;
throw exception;
}
videoLayer = new (std::nothrow) CVideoLayer(this);
if(videoLayer == 0)
{
logger->log("Unable to create the video layer!");
std::bad_alloc exception;
throw exception;
}
}
IEngineLayer* createEngineLayer(void)
{
// Using std::nothrow would be a bad idea here as catching things thrown
// from the constructor is needed.
try
{
CEngineLayer* newLayer = new CEngineLayer;
return (IEngineLayer*)newLayer;
}
catch(std::bad_alloc& exception)
{
// Couldn't allocate enough memory for the engine layer.
return 0;
}
}
Run Code Online (Sandbox Code Playgroud)
我省略了大部分不相关的信息,但我认为这里的图片很清楚.
是否可以手动抛出std :: bad_alloc而不是单独尝试/捕获所有图层创建并在重新抛出bad_allocs之前进行记录?
小智 39
只是回答这个问题(因为似乎没有其他人回答过它),C++ 03标准定义std::bad_alloc
如下:
namespace std {
class bad_alloc : public exception {
public:
bad_alloc() throw();
bad_alloc(const bad_alloc&) throw();
bad_alloc& operator=(const bad_alloc&) throw();
virtual ˜bad_alloc() throw();
virtual const char* what() const throw();
};
}
Run Code Online (Sandbox Code Playgroud)
由于标准定义了一个公共构造函数,因此构造并从代码中抛出一个是非常安全的.(可以抛出具有公共拷贝构造函数的任何对象,IIRC).
Fré*_*idi 19
你不需要这样做.您可以使用throw
语句的无参数形式来捕获std::bad_alloc
异常,记录它,然后重新抛出它:
logger = new CLogger(this);
try {
videoLayer = new CVideoLayer(this);
} catch (std::bad_alloc&) {
logger->log("Not enough memory to create the video layer.");
throw;
}
Run Code Online (Sandbox Code Playgroud)
或者,如果logger
不是智能指针(它应该是):
logger = new CLogger(this);
try {
videoLayer = new CVideoLayer(this);
} catch (std::bad_alloc&) {
logger->log("Not enough memory to create the video layer.");
delete logger;
throw;
} catch (...) {
delete logger;
throw;
}
Run Code Online (Sandbox Code Playgroud)
小智 5
如果我在STL容器中使用一些自定义分配器,我个人会抛弃它.我们的想法是将相同的接口(包括行为方面)作为默认的std :: allocator呈现给STL库.
因此,如果您有自定义分配器(例如,从内存池分配一个)并且底层分配失败,请调用"throw std :: bad_alloc".这保证了调用者,其中99.9999%的时间是某个STL容器,将正确地对其进行调整.如果分配器返回一个大的胖0,你无法控制那些STL实现会做什么 - 它不太可能是你想要的任何东西.