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

Unix共享内存单标识符场景下多指针使用方案咨询

解决单共享内存ID下使用多个指针的问题

你的当前代码存在一个关键问题:两次调用Shmat会返回同一个共享内存段的起始地址,所以mem和mem2其实指向同一块内存的开头,完全达不到你想要的"多个指针访问不同区域"的效果。下面给你两种可行的解决方案,核心思路都是在同一个共享内存段内划分不同的区域,通过偏移或结构化的方式获取不同的指针。

方案一:通过内存偏移划分区域

如果你只是需要简单的不同类型/大小的内存块,可以直接计算总内存大小,分配后通过起始地址的偏移得到不同指针:

#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    // 定义需要的内存:1个int变量 + 50个char的缓冲区
    const size_t int_size = sizeof(int);
    const size_t char_buf_size = 50;
    const size_t total_shm_size = int_size + char_buf_size;

    // 创建共享内存段
    int idSh = shmget(IPC_PRIVATE, total_shm_size, IPC_CREAT | 0700);
    if (idSh == -1) {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    // 挂载共享内存到进程地址空间
    void* base_addr = shmat(idSh, NULL, 0);
    if (base_addr == (void*)-1) {
        perror("shmat failed");
        exit(EXIT_FAILURE);
    }

    // 通过偏移获取不同指针
    int* mem = (int*)base_addr;          // 指向共享内存起始的int区域
    char* mem2 = (char*)(base_addr + int_size); // 指向int区域之后的char缓冲区

    // 测试使用
    *mem = 1234;
    strcpy(mem2, "Hello Shared Memory!");

    printf("mem value: %d\n", *mem);
    printf("mem2 value: %s\n", mem2);

    // 记得卸载共享内存(实际开发中根据场景处理)
    shmdt(base_addr);
    shmctl(idSh, IPC_RMID, NULL);

    return 0;
}

方案二:使用结构体结构化共享内存

如果你的数据结构更复杂,推荐在共享内存中定义一个结构体,通过结构体成员来获取不同的指针,代码可读性更强:

#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义共享内存中的数据结构
typedef struct {
    int counter;
    char message[100];
    float temperature;
} SharedData;

int main() {
    const size_t total_shm_size = sizeof(SharedData);

    // 创建共享内存
    int idSh = shmget(IPC_PRIVATE, total_shm_size, IPC_CREAT | 0700);
    if (idSh == -1) {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    // 挂载并转为结构体指针
    SharedData* shared_data = (SharedData*)shmat(idSh, NULL, 0);
    if (shared_data == (void*)-1) {
        perror("shmat failed");
        exit(EXIT_FAILURE);
    }

    // 获取指向不同成员的指针
    int* mem = &shared_data->counter;
    char* mem2 = shared_data->message;
    float* mem3 = &shared_data->temperature;

    // 测试使用
    *mem = 99;
    strcpy(mem2, "Structured shared memory works!");
    *mem3 = 25.6f;

    printf("Counter: %d\n", *mem);
    printf("Message: %s\n", mem2);
    printf("Temperature: %.1f\n", *mem3);

    // 清理资源
    shmdt(shared_data);
    shmctl(idSh, IPC_RMID, NULL);

    return 0;
}

关键注意事项

  • 永远不要忽略shmget和shmat的返回值检查,这些系统调用很容易因为权限、内存不足等原因失败。
  • 跨进程使用时,不要在共享内存中存放指针(比如char*类型的成员),因为不同进程的地址空间映射不同,指针在其他进程中无效。直接存放实际数据(比如固定大小的数组)才是安全的。
  • 使用完共享内存后,记得通过shmdt卸载,以及shmctl(IPC_RMID)删除(避免系统资源泄漏)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:36:32