在C++中使用gcc浮点指针转换导致SIGBUS错误

Ham*_*alc 2 c++ gcc pointers casting segmentation-fault

我有一个动态定义的无符号8位整数数组:

const uint8_t *data;
Run Code Online (Sandbox Code Playgroud)

它包含一个字节流,并被重新解释为各种数据类型.我可以通过以下方式将此数据流中的位置n重新解释为基本类型类型:

type value =  *((type*) &data[n]);
Run Code Online (Sandbox Code Playgroud)

这适用于在Windows下使用Visual Studio编译器的所有数据类型,但是在Linux下使用gcc进行编译时,如果type为float(取消引用的位置在数据数组的范围内),则会创建SIGBUS错误.进一步的调查表明,引用此错误的是指针解除引用.我已经通过使用memcpy解决了这个问题,但是想知道为什么这会导致问题,因为引用的地址是有效的.reinterpret_cast会更合适,如果是,为什么?

编辑:

我没有提到Linux系统有ARM架构.@MSalters在下面指出,差异配置可能有更严格的指针对齐要求.一项简短的研究表明,虽然上述内容在x86架构上有效(尽管C/C++标准不允许),但ARM上的未对齐指针解除引用会导致总线错误.

MSa*_*ers 5

演员确实是个问题.它已经是一个reinterpret_cast,即使您使用旧的C语法.但只有在&data[n]实际有效时才允许演员表float*.SIGBUS意味着它不是.地址可能是有效char*地址,但这并不意味着它是有效float*地址.特别是,float*可能有更严格的对准要求.


Max*_*kin 5

正如 MSalters 在此线程中提到的,转换的目标类型的对齐要求比源类型的对齐要求更强,这会导致SIGBUSCPU 不处理未对齐的访问。

处理这个问题的方法是memcpy

const uint8_t *data = ...;
type value;
memcpy(&value, data, sizeof value);
Run Code Online (Sandbox Code Playgroud)