[英]Typecasting Arrays for Variable Width Access
对不起,我不确定我是否准确地写了标题。
但首先,这是我的限制:
执行以下操作有哪些注意事项
uint8_t some_function(uint16_t offset_addr) //16bit address
{
uint8_t Array[0x100];
uint8_t data_byte = 0xAA;
uint16_t data_word;
uint32_t data_double = 0xBEEFFACE;
\\ A. Storing wider-data into the array
*((uint32_t *) &Array[offset_addr]) = data_double;
\\ B. Reading multiple-bytes from the array
data_word = *((uint16_t *) &Array[offset_addr]);
return 0;
}
我知道我可以尝试按字节写入数据,但是由于位移,这会很慢。
这种用法会不会有很大的问题? 我已经在我的硬件上运行了它,到目前为止还没有发现任何问题,但我想注意这个实现可能导致的潜在问题。
这种用法会不会有很大的问题?
它会产生未定义的行为。 因此,即使在实践中,在您当前的 C 实现、硬件、程序和数据上表现出您的意图,您也可能会发现当某些(任何东西)发生变化时它会意外中断。
即使编译器以明显的方式实现强制转换和取消引用(它没有义务这样做,因为 UB),由您的方法导致的未对齐访问至少会减慢许多 CPU,并且会在一些 CPU 上产生陷阱。
做你想做的符合标准的方法是这样的:
uint8_t some_function(uint16_t offset_addr) {
uint8_t Array[0x100];
uint8_t data_byte = 0xAA;
uint16_t data_word;
uint32_t data_double = 0xBEEFFACE;
\\ A. Storing wider-data into the array
memcpy(Array + offset_addr, &data_double, sizeof data_double);
\\ B. Reading multiple-bytes from the array
memcpy(&data_word, Array + offset_addr, sizeof data_word);
return 0;
}
这不一定比您的版本慢,并且只要您不超出数组的范围,它就已经定义了行为。
这可能没问题。 很多人都做过这样的事情。 C 在这种情况下表现良好。
需要注意的两件事:
缓冲区溢出。 你知道那些像 Eternal Blue 这样的零日和像 WannaCry 这样的黑客吗? 他们中的许多人利用了像您这样的代码中的错误。 恶意输入导致代码将太多内容写入数据结构,如uint8_t Array[0x100]
。 当心。 避免像您所做的那样在堆栈上分配缓冲区(作为函数局部变量),因为破坏堆栈是可利用的。 让它们足够大。 检查你没有超越他们。
机器字节排序与网络字节排序,也就是字节序。 如果这些数据结构通过网络在机器之间移动,您可能会遇到麻烦。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.