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

C语言中mmap映射文件如何按指定struct大小分块访问数据

解决方法

核心实现逻辑

你已经将mmap返回的地址强转为struct mapped *类型,C语言的指针算术会自动按照目标类型的大小做偏移,不需要手动计算字节数。你有3个连续的struct实例,直接通过数组下标或者指针偏移就能访问后面2个数据块:

  • data[0] 对应第一个struct实例(你已经可以正常访问)
  • data[1] 对应第二个struct实例
  • data[2] 对应第三个struct实例

注意修复现有代码的问题

现有代码存在权限不匹配的隐患:你调用open时用了O_RDONLY只读权限,但mmap指定了PROT_READ | PROT_WRITE读写权限,运行时会触发mmap失败,需要根据你的使用场景调整:

  • 如果需要修改映射数据:把open的flag改成O_RDWR
  • 如果只需要读数据:把mmap的PROT参数改成PROT_READ

另外建议添加以下校验逻辑避免运行错误:

  1. 检查mmap返回值是否为MAP_FAILED,避免映射失败访问非法地址
  2. 校验文件大小是否等于3 * sizeof(struct mapped),避免文件大小不符合预期导致越界访问
  3. 确保struct没有内存对齐填充,和文件块布局完全一致,可以给struct添加__attribute__((packed))编译器属性(GCC/Clang环境下)避免自动对齐插入的填充字节。

修改后的完整代码示例

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h> 
#include <sys/stat.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdbool.h>

// 加packed避免结构体自动填充,确保大小为128字节
struct __attribute__((packed)) mapped
{
    /* 在这里填写你的结构体字段,确保总大小128字节 */
};


int main (int argc, char **argv){
    // 如果不需要写,保持O_RDONLY即可,后面mmap权限对应修改
    int fd = open("file", O_RDWR, S_IRUSR | S_IWUSR);
    if (fd == -1) {
        perror("open file failed");
        exit(EXIT_FAILURE);
    }

    struct stat st;
    if(fstat(fd, &st) == -1) {
        perror("get file stat failed");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 校验文件大小是否符合预期
    if (st.st_size != 3 * sizeof(struct mapped)) {
        fprintf(stderr, "file size mismatch, expected %zu, got %lld\n", 
                3 * sizeof(struct mapped), (long long)st.st_size);
        close(fd);
        exit(EXIT_FAILURE);
    }

    struct mapped *data = mmap(NULL, st.st_size, 
                                PROT_READ | PROT_WRITE, 
                                MAP_PRIVATE, fd, 0);
    if (data == MAP_FAILED) {
        perror("mmap failed");
        close(fd);
        exit(EXIT_FAILURE);
    }
   
    printf("File size: %lld\n", (long long)st.st_size);
    printf("struct mapped size: %zu\n", sizeof(struct mapped));
    printf("Total struct count: %zu\n", st.st_size / sizeof(struct mapped));

    // 遍历访问所有3个struct实例
    for (int i = 0; i < 3; i++) {
        printf("\n===== struct %d content =====\n", i);
        // 这里替换为你自己的打印逻辑,比如printf("%d\n", data[i].xxx);
    }

    close(fd);
    munmap(data, st.st_size);
    exit(EXIT_SUCCESS);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 02:27:06