1

我有一个现有的 C++ 项目,我想移植到 android。不幸的是,该程序在 android 上导致“致命信号 7 (SIGBUS)”错误。它在其他平台(32 位/64 位 Linux 和 Windows)上运行良好。这是导致问题的代码部分:

RawMem3::RawMem3(uint8_t packet_version, uint32_t flags, uint64_t packet_id,
    uint64_t packet_nr, uint64_t timestamp, vector<uint16_t>& nr_channels,
    vector<uint16_t>& samples_per_channel, vector<double>& data) :
    size_(0) {

size_ = sizeof(packet_version) + sizeof(size_) + sizeof(flags)
        + sizeof(packet_id) + sizeof(packet_nr) + sizeof(timestamp)
        + nr_channels.size() * sizeof(boost::uint16_t)
        + samples_per_channel.size() * sizeof(boost::uint16_t)
        + data.size() * sizeof(float); // FIXXXXXME  ...  hardcoded sizeof() !!!!

mem_ = malloc(size_);

uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
*ui8_ptr++ = packet_version;

uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(ui8_ptr);
*ui32_ptr++ = size_;
*ui32_ptr++ = flags;

uint64_t* ui64_ptr = reinterpret_cast<uint64_t*>(ui32_ptr);
*ui64_ptr++ = packet_id;
*ui64_ptr++ = packet_nr;

uint64_t* time_ptr = reinterpret_cast<uint64_t*>(ui64_ptr);
*time_ptr++ = timestamp;

uint16_t* ui16_ptr = reinterpret_cast<uint16_t*>(time_ptr);

for (unsigned int n = 0; n < nr_channels.size(); n++)
    *ui16_ptr++ = nr_channels[n];
for (unsigned int n = 0; n < samples_per_channel.size(); n++)
    *ui16_ptr++ = samples_per_channel[n];

try {
    float* flt_ptr = reinterpret_cast<float*>(ui16_ptr);
    for (unsigned int n = 0; n < data.size(); n++)
        *flt_ptr++ = numeric_cast<float>(data[n]);
} catch (negative_overflow& e) {
    cerr << "RawMem -- Constructor: " << e.what();
} catch (positive_overflow& e) {
    cerr << "RawMem -- Constructor: " << e.what();
} catch (bad_numeric_cast& e) {
    cerr << "RawMem -- Constructor: " << e.what();
}

严格来说它的这部分:

uint32_t* ui32_ptr = reinterpret_cast<uint32_t*>(ui8_ptr);
*ui32_ptr++ = size_;
*ui32_ptr++ = flags

我想这是一个对齐问题。我不是这方面的专家,所以有什么想法可以解决这个问题吗?我已经尝试更改packet_versionuint32_t. 之后 SIGBUS 错误消失了,但是我的客户端软件假设packed_versionuint8_t. 我无法更改客户端代码,因此我需要以不同的方式解决此问题。

4

1 回答 1

3

使用memcpy()而不是分配:

#define APPEND(x) memcpy(ui8_ptr, &(x), sizeof((x))); ui8_ptr += sizeof((x));

uint8_t* ui8_ptr = reinterpret_cast<uint8_t*>(mem_);
APPEND(packet_version);
APPEND(size_);
APPEND(flags);
APPEND(packet_id);
APPEND(packet_nr);
APPEND(timestamp);
for (unsigned int n = 0; n < nr_channels.size(); n++)
    APPEND(nr_channels[n]);
for (unsigned int n = 0; n < samples_per_channel.size(); n++)
    APPEND(samples_per_channel[n]);
for (unsigned int n = 0; n < data.size(); n++) {
    float qq = numeric_cast<float>(data[n]);
    APPEND(qq);
}
于 2013-11-17T11:29:15.160 回答