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

C++子进程访问共享内存值异常:读取returnLicense结果始终为0

问题根因及修复方案

你代码存在3个核心错误导致共享内存读写不符合预期:

    1. 指针参数值传递导致主进程的共享内存地址未正确赋值
      initSharedMemory函数的入参License *l是值传递,函数内部对l的赋值仅修改了栈上的形参副本,main函数中定义的License *l始终是未初始化的野指针,后续tmp->initLicense(num)属于非法内存访问,结果完全不可预期。
      修复方案:将参数改为指针引用,修改函数定义为:
int initSharedMemory (License *&l) {
    1. 共享内存申请大小错误
      shmget的第二个参数你传入的是sizeof(l),l是指针类型,32位系统下占4字节、64位系统下占8字节,远小于License结构体的实际大小,共享内存根本没有足够空间存储完整的License对象。
      修复方案:将两处shmget的大小参数改为sizeof(License):
// 父进程申请
int shmid = shmget(key, sizeof(License), 0666|IPC_CREAT);
// 子进程获取
int shmid = shmget(key, sizeof(License), 0666);
    1. C++类在共享内存中的使用限制
      如果你的License类包含虚函数、std::string/std::vector这类动态分配内存的成员,或者自定义了非平凡的构造/析构函数,直接放到共享内存中跨进程访问必然出错:虚函数表指针、动态内存的指针在不同进程的地址空间中完全无效。
      修复方案:确保License是标准布局类型,可以用static_assert(std::is_standard_layout_v<License>, "License must be standard layout");做编译期校验,所有成员都使用固定大小的数组/基础类型,不要包含任何动态内存分配逻辑。

修正后核心代码示例

// 仅展示修改部分
int initSharedMemory (License *&l) { // 改为指针引用
    key_t key = ftok("/tmp", 'J');
    cout << "key: " << key << endl;
    int shmid = shmget(key, sizeof(License), 0666|IPC_CREAT); // 调整申请大小
    if (shmid == -1) {
        perror("Shared memory");
        return -1;
    }
    l = (License*)shmat(shmid, (void*)0, 0);
    if (l == (void*) -1) {
        perror("Shared memory attach");
        return -1;
    }
    // 额外补充:第一次创建共享内存时主动初始化对象,避免脏数据
    new (l) License(); // 定位new显式构造对象
    return shmid;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:45:00