我试图使用std::unique_ptr<T[]>自定义内存分配器.基本上,我有自定义分配器,它们是子类IAllocator,提供以下方法:
void* Alloc( size_t size )
template<typename T> T* AllocArray( size_t count )
void Free( void* mem )
template<typename T> void FreeArray( T* arr, size_t count )
Run Code Online (Sandbox Code Playgroud)
由于底层内存可能来自预先分配的块,我需要特殊的...Array()方法来分配和释放数组,它们分配/释放内存并调用T()/ ~T()范围内的每个元素.现在,据我所知,自定义删除器std::unique_ptr使用签名:
void operator()(T* ptr) const
Run Code Online (Sandbox Code Playgroud)
在这种情况下unique_ptr<T[]>,通常你会调用delete[]并完成它,但我必须调用FreeArray<T>,为此我需要该范围内的元素数量.只给出了原始指针,我认为没有办法获得范围的大小,因此我唯一能想到的就是:
std::unique_ptr<T[], MyArrDeleter> somePtr( allocator.AllocArray<T>( 20 ), MyArrDeleter( allocator, 20 ) );
Run Code Online (Sandbox Code Playgroud)
基本上,必须手动将数组的大小传递给删除对象.有一个更好的方法吗?这对我来说似乎很容易出错......
我知道从析构函数中抛出异常是不安全的,但是从构造函数中抛出异常是不安全的?
例如,全局声明的对象会发生什么?使用gcc进行快速测试,我得到了中止,是否始终保证?你会用什么解决方案来迎合这种情况?
是否有任何情况下构造函数可以抛出异常而不是留下我们期望的东西.
编辑:我想我应该补充一点,我试图理解在什么情况下我可以获得资源泄漏.看起来明智的做法是手动释放我们在抛出异常之前通过构造获得的资源.我从来不需要在今天之前在构造函数中抛出异常,所以试图理解是否存在任何陷阱.
即这也安全吗?
class P{
public:
P() {
// do stuff...
if (error)
throw exception
}
}
dostuff(P *p){
// do something with P
}
...
try {
dostuff(new P())
} catch(exception) {
}
Run Code Online (Sandbox Code Playgroud)
分配给对象P的内存是否会被释放?
EDIT2:忘了提到在这种特殊情况下,dostuff将对P的引用存储在输出队列中.P实际上是一条消息,dostuff接收消息,将其路由到适当的输出队列并发送它.基本上,一旦dostuff持有它,它会在后来的dostuff内部释放.我想我想把一个autoptr放在P周围并在dostuff后调用autoptr上的释放以防止内存泄漏,这是正确的吗?