C++ 普通旧数据和“std::memcpy”对齐问题
为了回应这个问题,我提出了一个解决方案,使用C++ 普通旧数据和“std::memcpy”对齐问题,c++,memcpy,memory-alignment,C++,Memcpy,Memory Alignment,为了回应这个问题,我提出了一个解决方案,使用std::memcpy()将泛型类型存储在chars的缓冲区中 我的怀疑是存储POD时可能出现的内存对齐问题(我知道使用not POD类型,如std::string,是非常危险的) 简而言之:以下程序存在内存对齐问题 如果是的话,可以编写类似的东西(将POD值存储在char缓冲区中)来确保安全?怎么做 #include <cstring> #include <iostream> int main() { char b
std::memcpy()
将泛型类型存储在char
s的缓冲区中
我的怀疑是存储POD时可能出现的内存对齐问题(我知道使用not POD类型,如std::string
,是非常危险的)
简而言之:以下程序存在内存对齐问题
如果是的话,可以编写类似的东西(将POD值存储在char
缓冲区中)来确保安全?怎么做
#include <cstring>
#include <iostream>
int main()
{
char buffer[100];
double d1 { 1.2 };
std::memmove( buffer + 1, & d1, sizeof(double) );
double d2;
std::memmove( & d2, buffer + 1, sizeof(double) );
std::cout << d2 << std::endl;
return 0;
}
#包括
#包括
int main()
{
字符缓冲区[100];
双d1{1.2};
标准::memmove(缓冲区+1,&d1,大小f(双));
双d2;
std::memmove(&d2,缓冲区+1,大小f(双));
这是安全的
[basic.types]/2:
对于任何普通可复制类型T
,如果指向T
的两个指针指向不同的T
对象obj1
和obj2
,其中
如果复制了构成obj1
的底层字节(1.7),则obj1
和obj2
都不是基类子对象
在obj2
中,obj2
随后应保持与obj1
相同的值
由于double
是可复制的,因此您的代码定义良好。您可以在未对齐的缓冲区之间进行复制。您不能做的是将缓冲区强制转换为double*,然后作为double直接对内存中的值进行操作。这通常会由于对齐问题而导致错误。这应该可以工作。通常情况下,应该ck sizeof()小于固定缓冲区,但双精度当然比这里使用的100小得多。@Gregg-当然;我使用100
来避免对缓冲区大小的怀疑。“从技术上讲,为字符分配随机字节是未定义的,因为陷阱表示法。”不符合标准。[basic.types]/2表示可以使用char
或unsigned char
对对象进行琐碎的复制。因此,这是标准中的一个小问题。char允许使用陷阱表示,其中一个子句必须不正确。事实上,作者点头,类型必须是unsigned char。没有小问题。char
允许进行签名或unsignedd、 signed char
可能有也可能没有陷阱表示。为了使实现符合标准,如果signed char
可以陷阱,那么char
就不能被签名。因此2的补码signedchar
类型是完全有效的。标准中还有其他地方有这样的要求,例如对char
的UTF-8要求(能够在char
和unsigned char
之间转换任何UTF-8代码需要char
not trap)。编辑以删除关于字符捕获的语句。我怀疑不是: