C++ C++;指针算法:对齐异常(0x801)

C++ C++;指针算法:对齐异常(0x801),c++,casting,pointer-arithmetic,C++,Casting,Pointer Arithmetic,我得到了一个非常奇怪的对齐异常,它只发生在某些硬件组合上。 我已经实现了一个蓝牙音频接收器,它从unix文件描述符获取数据。当我将Macbook Pro(作为蓝牙源)和raspberry pi(作为蓝牙接收器)组合在一起时,我会在以下位置出现对齐异常: void process(uint8_t* inData, uint32_t size, float* outData) { int16_t* from = (int16_t*)inData; float* to = outDat

我得到了一个非常奇怪的对齐异常,它只发生在某些硬件组合上。 我已经实现了一个蓝牙音频接收器,它从unix文件描述符获取数据。当我将Macbook Pro(作为蓝牙源)和raspberry pi(作为蓝牙接收器)组合在一起时,我会在以下位置出现对齐异常:

void process(uint8_t* inData, uint32_t size, float* outData)
{
    int16_t* from = (int16_t*)inData;
    float* to = outData;

    for (size_t i = 0; i < size/2; ++i) {
        *to = *from/32767.0;
        ++to;
        ++from; // Crashes on MacbookPro/RasPi combination
    }
}
void进程(uint8\u t*inData、uint32\u t size、float*outData)
{
int16_t*from=(int16_t*)inData;
浮动*至=输出数据;
对于(尺寸i=0;i
怎么会这样?我的水槽显然不知道我的来源。这适用于其他平台(组合)

我也试过这个片段,但是也没有成功

int8_t* from = (int8_t*)inData;
float* to = outData;

for (size_t i = 0; i < size/2; ++i) {
    int16_t tmp;
    std::memcpy(&tmp, from, 2);
    *to = tmp/32767.0;
    ++to;
    from += 2; // This crashes
}

int8_t*from=(int8_t*)inData;
浮动*至=输出数据;
对于(尺寸i=0;i

我想一个运行的示例在这里没有帮助,因为当使用另一个数据(蓝牙)源时,完全相同的代码工作。

您将指向8位值的指针视为指向16位值的指针。这是未定义的

此外,通常,8位值的对齐方式为1字节,其中16位值的am对齐方式为2字节


正如Eljay在评论中所说,您可以更改
inData
的对齐方式,但结果仍然没有定义

将指向8位值的指针视为指向16位值的指针。这是未定义的

此外,通常,8位值的对齐方式为1字节,其中16位值的am对齐方式为2字节

正如Eljay在评论中所说,您可以更改
inData
的对齐方式,但结果仍然没有定义

这解决了它:

    char* to; // = ...
    char* from; // = ...

    for (size_t i = 0; i < buffer.size()/size(conf.codec); ++i) {
        int16_t tmp;
        std::memcpy(&tmp, from+(i*2), 2);
        float f = tmp/32767.0;
        std::memcpy(to+(i*4), &f, 4);
    }
char*to;//=。。。
char*from;//=。。。
对于(size_t i=0;i
这将修复它:

    char* to; // = ...
    char* from; // = ...

    for (size_t i = 0; i < buffer.size()/size(conf.codec); ++i) {
        int16_t tmp;
        std::memcpy(&tmp, from+(i*2), 2);
        float f = tmp/32767.0;
        std::memcpy(to+(i*4), &f, 4);
    }
char*to;//=。。。
char*from;//=。。。
对于(size_t i=0;i
确保
inData
指针对其指向的内容进行了正确的
int16\u t
对齐。我使用的是sbc解码器库,从数据中清楚地对齐为int16\u t:int16\u t;//=。。。。字符*ptr;//=。。。如果(sbc->endian==sbc_BE){*ptr++=(s&0xff00)>>8;*ptr++=(s&0x00ff);}其他{*ptr++=(s&0x00ff);*ptr++=(s&0xff00)>>8;}确保
inData
指针对其指向的内容进行了正确的
int16\u t
对齐。我正在使用的sbc解码器lib from Data清楚地对齐为int16\u t:int16\u t;/=。。。。字符*ptr;//=。。。如果(sbc->endian==sbc_BE){*ptr++=(s&0xff00)>>8;*ptr++=(s&0x00ff);}其他{*ptr++=(s&0x00ff);*ptr++=(s&0xff00)>>8;}我认为字符指针(未指定、无符号、有符号,包括
int8_t*
)不受别名禁止规则的约束。请参阅。第一个问题的最后一部分指定了可以使用的类型
char
是其中之一,但我不知道它扩展到了
uint_8
我认为char指针(未指定、无符号、有符号,包括
int8_*
)不受禁止别名规则的约束。请参阅。第一个问题的最后一部分指定了可以使用的类型
char
是其中之一,但我不知道它扩展到
uint_8
memcpy
是从字节缓冲区转换到正确的类型(具有正确的对齐方式)是处理问题的一种好方法。它可能会与endian问题发生冲突,但只要数据都在同一个平台上,就不应该成为问题。
memcpy
是从字节缓冲区到正确类型(具有正确对齐方式)的一种处理问题的好方法。它可能会与endian问题发生冲突,但只要数据都在同一个平台上,就不应该成为问题。