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

15年前的mmap教程运行异常,是教程错误还是GCC编译问题?

问题根源

这是教程代码本身存在的数组越界访问bug,具体原因如下:

  • 代码中定义NUMINTS=1000,内存映射的区域总大小是1000 * sizeof(int),对应int类型数组的合法下标范围是0 ~ 999,但读写代码的循环均写为for (i = 1; i <=NUMINTS; ++i),直接访问了map[1000]这个越界地址,属于C语言标准规定的未定义行为,不同运行场景下结果不一致是正常表现。
  • 两种运行结果的差异是Linux文件系统、内存管理的特性共同导致的:
    • 当/tmp/mmapped.bin不存在时,新建文件的磁盘块、对应的内存映射页均为全新分配,越界的map[1000]刚好落在映射区后未被占用的匿名内存页上,写入的2000暂时保存在该页中,读取时就能拿到对应值。
    • 当文件预先存在时,open指定的O_TRUNC标志会清空原有文件内容,旧的磁盘块被系统回收并清零,扩充文件大小后映射的内存边界刚好卡在map[999]的末尾,越界写入的2000不会同步到文件中,读取时就拿到了对应位置的初始0值。
修复方法

调整循环的下标范围,避免越界访问即可,参考修改如下:

// mmap_write.c 写入循环修改
for (i = 0; i < NUMINTS; ++i) {
    map[i] = 2 * (i + 1); 
}

// mmap_read.c 读取循环修改
for (i = 0; i < NUMINTS; ++i) {
    printf("%d: %d\n", i + 1, map[i]);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 00:45:03