You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

QSharedMemory创建和读取时返回大小不一致的原因及解决方法

大小不一致的原因

这个现象是操作系统层面的正常行为,不属于QSharedMemory的bug:

  • 所有主流操作系统的共享内存分配最小单位都是内存页(默认大小通常为4096字节),你申请的大小如果不是页大小的整数倍,系统会自动向上对齐到最近的页大小整数倍。你遇到的数值刚好符合这个规则:658824 ÷ 4096 ≈ 160.85,向上取整161页,161×4096 = 659456,和你读取到的共享内存大小完全一致。
  • 你提到的偶发大小正确的情况,是因为前次运行的共享内存段没有被正常释放,程序附着到了残留的旧共享内存段上,读取到了旧段的大小值,重启后系统清理了残留段,就会回到对齐后的正确大小。

你当前用空字符截断的临时方案风险很高:如果存储的是带\0的二进制数据(图片、序列化结构体等),会直接导致数据被异常截断,完全不可靠。


标准解决方案(非临时 workaround)

共享内存通信的通用规范是:在共享内存开头固定预留定长字节存储实际写入的数据长度,写入端先写长度再写业务数据,读取端先读长度字段再取对应长度的内容即可,完全不受系统页对齐的影响。

写入端修改示例

int dataSize = buffer->size();
// 总申请大小 = 长度字段大小(用定长类型quint32,避免跨架构位宽差异) + 实际业务数据大小
int totalApplySize = sizeof(quint32) + dataSize;
if (!m_sharedMemory->create(totalApplySize)) {
    qCritical() << tr("Unable to create shared memory segment.");
    // 可选:创建失败时先尝试清理残留的旧共享内存段再重试创建
    // if (m_sharedMemory->attach()) { m_sharedMemory->detach(); } 再重新调用create
    return;
}
m_sharedMemory->lock();
char *memStart = (char*)m_sharedMemory->data();
// 第一步:写入实际业务数据的长度
*reinterpret_cast<quint32*>(memStart) = dataSize;
// 第二步:写入实际业务数据,偏移长度字段的大小
memcpy(memStart + sizeof(quint32), buffer->data(), dataSize);
m_sharedMemory->unlock();

读取端修改示例

QSharedMemory sharedMemory(sharedMemoryName);
if (!sharedMemory.attach(QSharedMemory::AccessMode::ReadOnly)) {
    qCritical() << "Unable to attach to shared memory segment.";
    return nullptr;
}
sharedMemory.lock();
const char *memStart = (const char*)sharedMemory.constData();
// 第一步:读取开头的长度字段,拿到真实业务数据的大小
quint32 realDataSize = *reinterpret_cast<const quint32*>(memStart);
// 第二步:读取对应长度的业务数据即可
QByteArray realData(memStart + sizeof(quint32), realDataSize);
sharedMemory.unlock();

// 后续直接使用realData即可,不需要关注共享内存的实际对齐后大小

内容的提问来源于stack exchange,提问作者Duesentrieb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 11:24:01