mincequi
mincequi

Reputation: 55

C++ pointer arithmetic: alignment exception (0x801)

I got a very strange alignment exception, which only occurs on certain hardware combinations. I have implemented a bluetooth audio sink, which get its data fed from a unix file descriptor. When i combine a Macbook Pro (as bluetooth source) and a raspberry pi (as bluetooth sink), i get an alignment exception at the following point:

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
    }
}

How comes? My sink obviously does not know about my source. And this works for other platforms (combinations)?

I also tried this snippet, however, also no success.

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
}

I guess a running example would not help here, since the exact same code works, when using another data (bluetooth) source.

Upvotes: 0

Views: 266

Answers (2)

mincequi
mincequi

Reputation: 55

This fixed it:

    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);
    }

Upvotes: 0

ChrisMM
ChrisMM

Reputation: 10105

You are treating a pointer to an 8-bit value as a pointer to a 16-bit value. This is undefined.

Further, typically, 8-bit values will have an alignment of 1 byte, where as a 16-bit value has am alignment of 2 bytes.

As Eljay said in the comments, you can change the alignment of inData, but the result is still not defined.

Upvotes: 2

Related Questions