c++怎么利用std::span在不拷贝数据的情况下修改文件缓冲区内容【详解】

陌静君_9514

陌静君_9514

2026-03-30

938人浏览

原创

c++oding="utf-8" ?>

std::span本身不修改文件缓冲区,仅提供对已有可写内存(如mmap映射区)的安全视图;需配合mmap/内存映射、写权限设置及msync/FlushViewOfFile刷盘才能持久化修改。

c++怎么利用std::span在不拷贝数据的情况下修改文件缓冲区内容【详解】

std::span 本身不能直接修改文件缓冲区

它只是对已有内存的“视图”,不管理内存生命周期,也不关联 I/O。想用 std::span 修改文件内容,前提是:你已经通过某种方式(比如 mmap、ReadFileMapping、或自定义分配器)拿到了可写且持久化的内存块地址——std::span 只是帮你安全、便捷地切片和访问它。

典型场景:mmap + std::span 修改二进制文件

Linux/macOS 下常用 mmap 将文件映射为进程内存,之后用 std::span 操作映射区域。Windows 需用 CreateFileMapping + MapViewOfFile,逻辑类似。

  • 必须用 PROT_WRITE(Linux)或 PAGE_READWRITE(Windows)打开映射权限,否则写入会触发 SIGBUS 或访问违规
  • 映射长度要覆盖你要修改的偏移+长度,std::span 的范围不能越界,否则行为未定义
  • 修改后需调用 msync(..., MS_SYNC)(Linux)或 FlushViewOfFile(Windows),否则改动可能不会落盘

示例(Linux 简化版):

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
int fd = open("data.bin", O_RDWR);
struct stat st;
fstat(fd, &st);
void* addr = mmap(nullptr, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
auto span = std::span(static_cast<uint8_t>(addr), st.st_size); // 安全切片
span[0x100] = 0xFF; // 直接改第 256 字节
msync(addr, st.st_size, MS_SYNC); // 强制刷盘
</uint8_t>

std::span 替代 raw pointer 的真正价值在哪

不是为了“不拷贝”——uint8_t* 本身也不拷贝;而是为了在传递、切片、边界检查(编译期/运行时)时更安全、更明确语义。

  • 传参时用 std::span 表明只读,避免意外写入
  • 函数内用 span.subspan(offset, len) 切出子区域,比手动算指针加法更不易出错
  • 启用 -D_GLIBCXX_CONCEPTS(GCC)或 libc++ 的调试模式后,越界访问可能触发断言,而 raw pointer 不会
  • 注意:默认构造的 std::span 是空的,别忘了检查 span.data() != nullptr,尤其从 C API 接收指针时

常见错误:把 std::span 当作“零拷贝 I/O 工具”

有人以为只要用了 std::span,读写文件就自动零拷贝——这是误解。真正的零拷贝依赖底层机制(如 mmap、io_uring、DPDK),std::span 只是上层视角的轻量封装。

  • 用 fread/std::ifstream::read 读到 vector 再构造 std::span?数据已经拷贝过了
  • 把 std::vector::data() 传给 std::span?没问题,但 vector 生命周期必须长于 span,否则悬垂
  • 跨线程共享一个 std::span?不行——span 本身无同步语义,底层内存仍需自己加锁或用原子操作

真正关键的是:谁分配内存、谁保证可写、谁负责刷盘。std::span 不参与这些,它只管“怎么看”。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

2023.09.20

2318

7

C++ 智能指针与现代内存管理
C++ 智能指针与现代内存管理

深入讲解 C++ 现代内存管理的核心工具——智能指针,涵盖 unique_ptr 独占所有权语义、shared_ptr 引用计数机制与循环引用问题、weak_ptr 弱引用的应用场景、make_unique/make_shared 工厂函数的性能优势、自定义删除器的编写、RAII 资源管理思想的实践,以及从裸指针迁移到智能指针的重构策略,帮助开发者编写安全无泄漏的现代 C++ 代码。

2026.04.23

379

31

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

2023.08.10

4498

6

go语言 数组和切片
go语言 数组和切片

本专题整合了go语言数组和切片的区别与含义,阅读专题下面的文章了解更多详细内容。

2025.09.03

1972

14

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.26

3339

3

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.07.27

2918

6

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

2023.08.01

1528

3

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

2639

5

windows无法访问共享电脑
windows无法访问共享电脑

在现代社会中,共享电脑是办公室和家庭的重要组成部分。然而,有时我们可能会遇到Windows无法访问共享电脑的问题。这个问题可能会导致数据无法共享,影响工作和生活的正常进行。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.08

3330

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习