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

System V共享内存shmat:如何存放单个int与结构体数组?

System V共享内存使用问题解答

问题1:单个int与结构体数组能否存入同一段共享内存?若需分开,是否要额外调用shmget和shmat?

  • 完全可以存入同一段共享内存,不需要分开。只需要计算好总内存大小(sizeof(int) + 数组元素个数 * sizeof(struct My_structure)),用这个总大小调用shmget即可,无需额外调用shmget和shmat。

问题2:如何正确编写带错误处理的shmat代码?当前代码出现“指针与整数比较”的警告

  • 警告原因:shmat失败时返回的是(void*)-1(指针类型),直接将其强制转换为struct My_structure*后和整数-1比较,C语言不允许指针与整数直接比较,因此触发警告。
  • 正确写法:先将shmat的返回值存入void*类型变量,与(void*)-1比较判断是否失败,再转换为目标指针类型:
void *shm_raw;
struct My_structure *shm_pointer;

if ((shm_raw = shmat(shm_id, NULL, 0)) == (void *)-1) {
    perror("shmat failed");
    exit(EXIT_FAILURE);
}
shm_pointer = (struct My_structure *)shm_raw;

问题3:如何让共享内存中的数据支持类似array[number]的数组式访问?

  • 由于共享内存中先存储单个int,再存储结构体数组,需要分别定位两者的内存地址:
    1. 单个int的地址就是共享内存的起始地址,直接转换为int*即可访问;
    2. 结构体数组的起始地址是共享内存起始地址加上单个int的大小,转换为struct My_structure*后,就可以像普通数组一样用下标访问。

完整示例代码

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

struct My_structure {
    char my_text[200];
    char my_name[20];
    int my_number;
};

int main(int argc, char *argv[]) {
    key_t key;
    int shm_id;
    void *shm_start;
    int *unrelated_singular_int;
    struct My_structure *struct_array;
    const int array_len = 5; // 假设结构体数组长度为5
    size_t total_shm_size = sizeof(int) + array_len * sizeof(struct My_structure);

    if (argc < 2) {
        fprintf(stderr, "Usage: %s <file_path>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    // 生成共享内存键值
    if ((key = ftok(argv[1], 2137)) == -1) {
        perror("ftok failed");
        exit(EXIT_FAILURE);
    }

    // 创建/获取共享内存段
    if ((shm_id = shmget(key, total_shm_size, 0644 | IPC_CREAT)) == -1) {
        perror("shmget failed");
        exit(EXIT_FAILURE);
    }

    // 挂载共享内存
    if ((shm_start = shmat(shm_id, NULL, 0)) == (void *)-1) {
        perror("shmat failed");
        exit(EXIT_FAILURE);
    }

    // 访问单个int变量
    unrelated_singular_int = (int *)shm_start;
    *unrelated_singular_int = 100;
    printf("Singular int value: %d\n", *unrelated_singular_int);

    // 访问结构体数组
    struct_array = (struct My_structure *)((char *)shm_start + sizeof(int));
    // 给数组元素赋值
    for (int i = 0; i < array_len; i++) {
        snprintf(struct_array[i].my_text, sizeof(struct_array[i].my_text), "Text for element %d", i);
        snprintf(struct_array[i].my_name, sizeof(struct_array[i].my_name), "Name_%d", i);
        struct_array[i].my_number = i * 10;
    }

    // 数组式访问示例
    printf("Element 2 - my_number: %d\n", struct_array[2].my_number);
    printf("Element 2 - my_name: %s\n", struct_array[2].my_name);

    // 卸载共享内存
    if (shmdt(shm_start) == -1) {
        perror("shmdt failed");
        exit(EXIT_FAILURE);
    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:11:17