struct CustomData
{
char flag;
int count;
double value;
};
CustomData custom_data{};
char *buf = new char[sizeof(CustomData) + 3];
memcpy(buf + 3, &custom_data, sizeof(CustomData));
CustomData* ptr = (CustomData *)(buf + 3);
ptr->count = 10;
ptr->value = 20.0;我有一个由头字节和结构组成的内存缓冲区。对于这个内存缓冲区,结构是memcpy。我必须修改这个嵌入式结构中的一些字段,就像上面演示的那样。
我的问题是:
memcpy到本地结构,修改它并将其复制回来肯定是可以的,但它似乎是浪费的。是否有方法检查ptr是否正确地对齐以确保对结构的安全访问?发布于 2021-12-30 11:45:07
C标准和C++标准都没有定义访问内存的行为,而不定义lvalue类型所需的对齐方式,甚至在指针值没有目标类型所需的对齐时,也没有定义将指针转换为另一个指针类型的行为。问题不在于您的目标体系结构(x86-64或其他)是否支持对齐访问,而是您的C或C++实现,特别是编译器是否支持它。
查看示例代码,我怀疑它是将数据从网络、文件或其他源复制到缓冲区的代理,然后尝试将该数据的一部分解释为所需的类型,可能是在检查接收数据中的头以确定主题数据的类型和/或位置之后。如果是这样的话,您应该描述原始情况,因为您显示的代理代码不够。
当将原始数据从网络或文件中读取为字节时,最好将数据直接读入所需的结构。理想情况下,将指定通信协议以根据需要对齐数据,以便在数据被接收到对齐缓冲区后不再需要进一步的操作。在C语言中,工会可以帮助处理将一种数据作为另一种数据混在一起的问题。
如果直接进入结构方法失败,memcpy可能会被使用,而且它可能不会像您想象的那样低效,因为memcpy方法会导致代码具有定义良好的行为,然后编译器通常可以在代码的相关部分有足够的可见性的情况下,优化它生成的程序集,这样就不会发生实际的memcpy。
否则,一些编译器对C和C++标准有不同的扩展,这些扩展允许您定义结构类型而不需要对齐,并可以使用任意类型访问内存(支持将字符数组作为其他类型进行混叠)。
至少在C中,动态分配的内存可以使用字符类型填充数据,然后按照有关“有效类型”的规则作为另一种类型访问。但是,必须遵守某些关于别名的规则,这不会允许访问不正确对齐的数据(没有使用上述扩展)。
发布于 2021-12-30 12:29:09
任何指针双关都是危险的,因为它可能打破严格的混叠规则。
您需要使用memcpy。大多数优化编译器都非常了解memcpy,并且通常不会发出对memcpy的实际调用。
typedef struct CustomData
{
char flag;
int count;
double value;
}CustomData;
CustomData *foo(int val, double d)
{
char *buf = new char[sizeof(CustomData) + 3];
CustomData cd;
cd.count = val;
cd.value = d;
memcpy(buf + 3, &cd, sizeof(cd));
return (CustomData *)buf;
}foo(int, double):
push rbp
mov ebp, edi
mov edi, 19
push rbx
sal rbp, 32
movq rbx, xmm0
sub rsp, 8
call operator new[](unsigned long)
mov QWORD PTR [rax+3], rbp
mov QWORD PTR [rax+11], rbx
add rsp, 8
pop rbx
pop rbp
rethttps://stackoverflow.com/questions/70531062
复制相似问题