Voi*_*tar 11 c++ pointers unique-ptr reinterpret-cast c++11
当使用具有可变大小结构的各种API(必须分配为byte []然后转换为struct的结构)时,如果unique_ptr持有者可以指向结构,那将是很好的,因为这是我们将要使用的.
例:
std::unique_ptr<VARIABLE_SIZE_STRUCT[]> v;
v.reset(reinterpret_cast<VARIABLE_SIZE_STRUCT*>(new BYTE[bytesRequired]));
Run Code Online (Sandbox Code Playgroud)
这允许`v为结构本身提供视图,这是优选的,因为我们不需要第二个变量,除了删除之外我们不关心字节指针.
问题在于可能会在演员表上敲击指针(使其免于安全).我认为没有合理的理由为什么编译器会改变转换时的指针值(因为没有继承),但是我听说标准保留了对任何转换的任何指针的权利,所以就符合标准的编码而言,办法是窗外的吧?或者有什么理由它是安全的吗?有没有办法至少static_assert这个,或其他一些方法来使它安全或干净地处理这种类型的结构?
你是对的,这是不安全的.但是,它可以使其安全.
该标准保证如果您reinterpret_cast使用其他类型,然后返回原始类型,则会返回原始值.
您可以将它与自定义删除器一起使用,以确保将内部指针强制转换为释放它之前分配的类型.
auto deleter = [](VARIABLE_SIZE_STRUCT* ptr)
{
delete[] reinterpret_cast<uint8_t*>(ptr);
};
std::unique_ptr<VARIABLE_SIZE_STRUCT, decltype(deleter)> v
(reinterpret_cast<VARIABLE_SIZE_STRUCT*>(new uint8_t[256]), deleter);
Run Code Online (Sandbox Code Playgroud)
在这一点上,你可能最好创建自己的包装器而不是使用unique_ptr.
您的分配可能没有所需的对齐方式 VARIABLE_SIZE_STRUCT
分配的内存中没有放置VARIABLE_SIZE_STRUCT的对象new- 假设你处理它,unique_ptr默认的析构函数逻辑应该找到要破坏的预期对象实例,但是释放本身就不会delete []在BYTE*-有定义的行为,你不得不自定义删除器调用第一~VARIABLE_SIZE_STRUCT(),然后delete[]...
如果您担心"thunking",可以在运行时进行检查:
BYTE* p;
v.reset(reinterpret_cast<VARIABLE_SIZE_STRUCT*>(p = new BYTE[bytesRequired]));
assert(reinterpret_cast<BYTE*>(v.get()) == p);
Run Code Online (Sandbox Code Playgroud)
背景 - 5.2.10/7:
可以将对象指针显式转换为不同类型的对象指针.当对象指针类型的prvalue v被转换为对象指针类型"指向cv T的指针"时,结果为
static_cast<cvT*>(static_cast<cv void*>(v)).将"指向T1的指针"类型的prvalue转换为"指向T2的指针"类型(其中T1和T2是对象类型,T2的对齐要求不比T1更严格)并返回其原始类型会产生原始类型指针值.
因此,如果对齐要求VARIABLE_SIZE_STRUCT比更严格BYTE,则无法保证使用检索原始指针reinterpret_cast<BYTE*>.