【发布时间】:2011-08-09 00:01:12
【问题描述】:
背景
我正在使用英特尔 IPP 加密库进行测试。
他们定义了几个不透明的结构,用于共享上下文,例如散列和加密,当然不能直接实例化。
要初始化这些不透明结构之一,您需要查询字节大小,然后动态分配一些字节并转换为结构指针。
他们的例子是这样的:
int byteSize = 0;
ippsSHA256GetSize(&byteSize);
// IppsSHA256State shaCtx; // Error: incomplete type is not allowed
IppsSHA256State * shaCtx = (IppsSHA256State *)(new uint8_t[byteSize]);
// use shaCtx
delete [] (uint8_t *)shaCtx;
问题
将它包装在作用域指针类中以便我不必担心释放的正确方法是什么?
我尝试过的事情
我认为以下内容是不安全的,因为在析构函数中调用 delete 将是 T 类型,而不是数组上的 delete []实际分配:
boost::scoped_ptr<IppsSHA256State> ctx(
reinterpret_cast<IppsSHA256State *>(new uint8_t[byteSize])
);
我考虑过的另一个(简化的)选项是我自己的一个简单的作用域指针类,但是那里的转换让我不确定这是否正确,尽管我对 reinterpret_cast 的理解是当转换时回到原来的类型,应该没有任何歧义:
template <typename T>
class IppsScopedState
{
public:
explicit IppsScopedState(size_t byteSize)
: _ptr(reinterpret_cast<T *>(new uint8_t[byteSize]))
{}
T * get() const { return _ptr; }
~IppsScopedState(void) {
if (_ptr) delete [] reinterpret_cast<uint8_t *>(_ptr);
}
private:
T * _ptr;
//NUKE_COPYASSIGN_CONSTRUCTORS
};
最后,我考虑了以上内容的细微变化:
template <typename T>
class IppsScopedState
{
public:
explicit IppsScopedState(size_t byteSize)
: _ptr(new uint8_t[byteSize])
{}
T * get() const { return reinterpret_cast<T *>(_ptr); }
~IppsScopedState(void) {
if (_ptr) delete [] _ptr;
}
private:
uint8_t * _ptr;
//NUKE_COPYASSIGN_CONSTRUCTORS
};
在任何一种情况下,用法都是这样的:
IppsScopedState<IppsSHA256State> ctx(byteSize); // after querying for the byteSize, of course
【问题讨论】:
标签: c++ casting smart-pointers opaque-pointers