我很好奇是否需要在堆栈上分配缓冲区以正确对齐任何类型,类似于 malloc
的工作方式,或者我是否会被迫使用类似 的东西std::aligned_storage
.
考虑以下代码块:
typedef enum _KEY_VALUE_INFORMATION_CLASS {
KeyValueBasicInformation = 0,
// Others
} KEY_VALUE_INFORMATION_CLASS;
typedef struct _KEY_VALUE_BASIC_INFORMATION {
ULONG TitleIndex;
ULONG Type;
ULONG NameLength;
WCHAR Name[1];
} KEY_VALUE_BASIC_INFORMATION, *PKEY_VALUE_BASIC_INFORMATION;
std::vector<std::wstring> RegistryKey::EnumerateValueNames() const
{
std::vector<std::wstring> result;
ULONG index = 0;
const ULONG valueNameStructSize = 16384 * sizeof(wchar_t) +
sizeof(KEY_VALUE_BASIC_INFORMATION);
// Stack buffer here
unsigned char buff[valueNameStructSize];
// Casted here
KEY_VALUE_BASIC_INFORMATION const* basicValueInformation =
reinterpret_cast<KEY_VALUE_BASIC_INFORMATION const*>(buff);
for(;;)
{
ULONG resultLength;
NTSTATUS errorCheck = PNtEnumerateValueKeyFunc(
hKey_,
index++,
KeyValueBasicInformation,
buff,
valueNameStructSize,
&resultLength);
if (NT_SUCCESS(errorCheck))
{
result.emplace_back(std::wstring(basicValueInformation->Name,
basicValueInformation->NameLength / sizeof(wchar_t)));
}
else if (errorCheck == STATUS_NO_MORE_ENTRIES)
{
break;
}
else
{
Win32Exception::ThrowFromNtError(errorCheck);
}
}
return result;
}
请注意值 buff
是如何放置在堆栈上的字符缓冲区,其大小可容纳给定的最大数据量。但是,我担心如果将此代码移植到另一个(例如 ARM 或 IA64)平台,则将缓冲区解释为字符串所需的转换可能会导致对齐错误。
编辑:如果有人好奇,我根据 std::aligned_storage
和 std::alignment_of
重做了这个:
std::vector<std::wstring> RegistryKey::EnumerateValueNames() const
{
std::vector<std::wstring> result;
ULONG index = 0;
const ULONG valueNameStructSize = 16384 * sizeof(wchar_t) +
sizeof(KEY_VALUE_BASIC_INFORMATION);
std::aligned_storage<valueNameStructSize,
std::alignment_of<KEY_VALUE_BASIC_INFORMATION>::value>::type buff;
auto basicValueInformation =
reinterpret_cast<KEY_VALUE_BASIC_INFORMATION*>(&buff);
for(;;)
{
ULONG resultLength;
NTSTATUS errorCheck = PNtEnumerateValueKeyFunc(
hKey_,
index++,
KeyValueBasicInformation,
basicValueInformation,
valueNameStructSize,
&resultLength);
if (NT_SUCCESS(errorCheck))
{
result.emplace_back(std::wstring(basicValueInformation->Name,
basicValueInformation->NameLength / sizeof(wchar_t)));
}
else if (errorCheck == STATUS_NO_MORE_ENTRIES)
{
break;
}
else
{
Win32Exception::ThrowFromNtError(errorCheck);
}
}
return std::move(result);
}
最佳答案
该标准对自动变量(或具有静态存储的变量)的对齐没有任何要求,除了编译器必须确保访问它们有效。
- C++03 3.9/5 类型
Object types have alignment requirements (3.9.1, 3.9.2). The alignment of a complete object type is an implementation-defined integer value representing a number of bytes; an object is allocated at an address that meets the alignment requirements of its object type
注意:这里的“对象类型”是指不是函数、引用或 void 类型的类型(即,它适用于 unsigned char
)。
获得对齐缓冲区的一种方法可能是声明 buff
像这样:
KEY_VALUE_BASIC_INFORMATION buff[valueNameStructSize/sizeof(KEY_VALUE_BASIC_INFORMATION) + 1];
你将能够摆脱 reinterpret_cast<>
启动。
关于c++ - 该标准是否要求自动存储中的对象对任何类型都具有正确的对齐方式(例如,如 malloc 那样)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9831445/