如何安全地将int复制到未对齐的字节数组中



我创建了一个字节数组uint8_t data[256],我想在任意位置读取和写入数据。位置偏移可以是任何数字,因此可能导致访问不对齐。例如,如果sizeof(int32_t) == 4,则position % sizeof(int32_t) != 0

它现在可以工作了,但据我所知,有些平台不直接支持未对齐的访问。在这种情况下,我也想让它发挥作用。

#include <cstdint>
#include <iostream>
void write(uint8_t* data, uint32_t position, int32_t value) {
int32_t* ptr = reinterpret_cast<int32_t*>(&data[position]);

*ptr = value;
}
int32_t read(uint8_t* data, uint32_t position) {
int32_t* ptr = reinterpret_cast<int32_t*>(&data[position]);

return *ptr;
}
int main()
{
uint8_t data[256];
int32_t value = 123456789;
uint32_t position = 1; // Example for unaligned access
write(data, position, value);

int32_t read_value = read(data, position);

std::cout << read_value << std::endl;
return 0;
}

如果这个问题有解决方案的话,我更喜欢使用标准库。

我在代码中没有看到new的位置,这使得两个reinterpret_cast的行为都是未定义的。只有在给定地址存在指定类型的对象时,才能取消引用返回的指针除了charstd::byteunsigned char,它们总是可以被取消引用。

如何序列化和反序列化对象的安全方法是通过std::memcpy:

void write(unsigned char* data, uint32_t position, int32_t value) {

std::memcpy(data+position,&value,sizeof(value));
}
int32_t read(unsigned char* data, uint32_t position) { 
int32_t result;
std::memcpy(&result,data+position,sizeof(result));
return result;
}

这也解决了任何对齐问题。

为了避免违反严格别名规则的可能问题,可以使用std::memcpy函数:

#include <cstring> // For std::memcpy
void write(uint8_t* data, uint32_t position, int32_t value)
{
std::memcpy(&data[position], &value, sizeof(value));
}
int32_t read(uint8_t* data, uint32_t position)
{
int answer;
std::memcpy(&answer, &data[position], sizeof(answer));
return answer;
}

从(第二个(链接的cppreference页面:

其中严格混叠禁止检查与的值相同的内存两种不同类型的std::memcpy可以用于转换值。

最新更新