C++11 make_unique的异常感知malloc版本
在C++11 make_unique的异常感知malloc版本,c++11,exception-handling,malloc,unique-ptr,placement-new,C++11,Exception Handling,Malloc,Unique Ptr,Placement New,在C++11中,没有make_unique(不能使用C++14),尽管人们可以很快被模仿成这样(已经有很多答案表明类似于此): 这似乎没问题,但在这里,异常处理完全被忽略了,new(ptr)T(…)如何工作,而不是new T(…),以及这如何影响任何版本的make_unique,尤其是在使用自定义分配方法时 首先,我知道抛出std::bad_alloc是不明智的,但是我相信最小意外的原则适用于这里,并且可以模拟new将要做的事情(即,在分配失败时抛出,而不是返回nullptr)。这就引出了两个问
C++11
中,没有make_unique
(不能使用C++14
),尽管人们可以很快被模仿成这样(已经有很多答案表明类似于此):
这似乎没问题,但在这里,异常处理完全被忽略了,new(ptr)T(…)
如何工作,而不是new T(…)
,以及这如何影响任何版本的make_unique
,尤其是在使用自定义分配方法时
首先,我知道抛出std::bad_alloc
是不明智的,但是我相信最小意外的原则适用于这里,并且可以模拟new
将要做的事情(即,在分配失败时抛出,而不是返回nullptr
)。这就引出了两个问题
1。将返回{nullptr}
替换为抛出std::bad_alloc()
?
2。要正确复制新T(…)的行为,如果构造函数抛出异常,则需要捕获异常,以便立即释放内存,然后重新抛出构造函数异常?
假设两者都是,下面是正确处理的情况还是有什么要考虑的?< /P>
template< typename T, typename ... Args >
auto malloc_make_unique_v2 (Args && ... args) -> std::unique_ptr< T, destroy_free< T > > {
if ( auto ptr = malloc( sizeof(T) ) ) try {
return { new ( ptr ) T( std::forward< Args >( args )... ) };
} catch( ... ) { // catch constructor exceptions
// assumed: memory allocated but object not constructed
free( ptr ); // release memory, object was not constructed?
throw; // propagate whatever the exception was during construction?
}
throw std::bad_alloc(); // no memory allocated, throw bad_alloc?
}
模板
自动malloc_make_unique_v2(Args&&…Args)->std::unique_ptr>{
如果(auto ptr=malloc(sizeof(T)),请尝试{
返回{new(ptr)T(std::forward(Args)…)};
}catch(…){//catch构造函数异常
//假定:已分配内存,但未构造对象
释放(ptr);//释放内存,对象未构造?
throw;//传播构造期间的异常吗?
}
抛出std::bad_alloc();//没有分配内存,抛出bad_alloc?
}
编辑-请注意,为了简单起见,我忽略了对齐
假设两者都是,下面是正确处理的情况还是有什么要考虑的?< /P>
template< typename T, typename ... Args >
auto malloc_make_unique_v2 (Args && ... args) -> std::unique_ptr< T, destroy_free< T > > {
if ( auto ptr = malloc( sizeof(T) ) ) try {
return { new ( ptr ) T( std::forward< Args >( args )... ) };
} catch( ... ) { // catch constructor exceptions
// assumed: memory allocated but object not constructed
free( ptr ); // release memory, object was not constructed?
throw; // propagate whatever the exception was during construction?
}
throw std::bad_alloc(); // no memory allocated, throw bad_alloc?
}
我觉得还可以
有一种方法可以使用自定义分配器分配的对象内存创建共享的_ptr。您所做的基本上是代码> > AlcalTeaION/<代码>,在标准C++中不存在(也许还没有)。也许您可以创建使用malloc/free的自定义分配器,然后实现您自己的分配器(如果您没有),并且
allocate\u unique
函数在出错时是否抛出或返回nullptr
,这是一个设计决策。但是,抛出一些错误并为其他错误返回nullptr
(您的第一个版本就是这样做的)的概念会让代码的用户感到困惑/烦恼。
template< typename T, typename ... Args >
auto malloc_make_unique_v2 (Args && ... args) -> std::unique_ptr< T, destroy_free< T > > {
if ( auto ptr = malloc( sizeof(T) ) ) try {
return { new ( ptr ) T( std::forward< Args >( args )... ) };
} catch( ... ) { // catch constructor exceptions
// assumed: memory allocated but object not constructed
free( ptr ); // release memory, object was not constructed?
throw; // propagate whatever the exception was during construction?
}
throw std::bad_alloc(); // no memory allocated, throw bad_alloc?
}