lus*_*r00 3 c c++ pointers iar
长话短说我在C中使用IAR EWARM编译器.
uint8_t packet[2048];
uint32_t* src = (uint32_t*)&packet[9];
uint32_t var = *src++;
Run Code Online (Sandbox Code Playgroud)
最后一行导致总线故障.
uint8_t packet[2048];
uint32_t* src = (uint32_t*)&packet[9];
uint32_t var = 0xFE;
*src++;
Run Code Online (Sandbox Code Playgroud)
现在没有公交车故障.我可以在调试器中看到src指向我希望它指向的数据.增量按预期工作但尝试读取它会导致总线故障.
有帮助吗?
&packet[9]可能没有正确对齐uint32_t.在ARM CPU上看到"总线错误"通常是对齐错误的标志.请参阅此处以获得对齐的说明.
在第二个例子中,它可能通过优化*操作来避免总线故障,因为您从不使用结果.
请注意,即使您修复此问题,代码仍会因违反严格别名规则而导致未定义的行为.(uint8_t可能没有别名uint32_t).有些编译器现在可能看起来"正常工作",但代码可能会在将来的任何时候中断.
代码的安全等价物是:
uint8_t *src = &packet[9];
uint32_t var;
memcpy(&var, src, sizeof var);
src += sizeof var;
Run Code Online (Sandbox Code Playgroud)
请注意,如果源数据被指定为具有整数的特定字节顺序(例如,您从网络流获取它而不是先前通过相同方法保存的数据),那么您将需要使用方法来读取数据与...的表示无关uint32_t.(换句话说,"endianness").