C++如何使用指针操作共享内存

夜枫姑娘_3612

夜枫姑娘_3612

2026-08-20

442人浏览

原创

安全声明需将void*强制转换为与共享内存写入时内存布局严格一致的具体类型指针(如Data*),且结构体须满足std::is_standard_layout_v && std::is_trivially_copyable_v,确保跨进程POD语义;转换后立即使用,避免悬空,并配合同步机制防竞争。

c++如何使用指针操作共享内存

共享内存映射后,指针怎么声明才安全

映射成功后得到的是 void*,不能直接解引用或算术运算。必须强转为具体类型的指针,且类型必须与写入/读取时的内存布局严格一致。比如写入端用 struct Data { int a; double b; }; 写了 16 字节,读取端就得用同样的 Data*,不能用 int* 或随意加偏移——否则未定义行为,尤其在不同编译器或开启优化时极易崩溃。

常见错误:把映射地址赋给 char* 后手动 memcpy,却忘了对齐。x86_64 上 double 要求 8 字节对齐,若映射起始地址是奇数,reinterpret_cast(ptr + 1) 可能触发 SIGBUS(ARM 更敏感)。

实操建议:

  • 统一用 static_assert(std::is_standard_layout_v && std::is_trivially_copyable_v, "shared struct must be POD"); 确保结构体可安全跨进程传递
  • 映射后立即转成目标类型指针:Data* shm_ptr = static_cast(mmap(...));
  • 避免裸指针长期持有;考虑封装成 RAII 类,在析构中自动 munmap 和 shm_unlink

多进程同时读写时,指针操作会引发什么竞争

指针本身只是地址,不带同步语义。两个进程都拿到 Data* 后,直接改 shm_ptr->a = 42; 就是纯裸写——没有原子性、没有缓存一致性保证、没有写顺序约束。结果可能是:一个进程看到 a=42 但 b 还是旧值,或看到 b 更新了但 a 没变,甚至读到字节错乱的中间状态(如 int 被部分覆盖)。

典型现象:数值偶尔突变为极大/极小值,结构体字段值“错位”,日志显示写入顺序和读取顺序不一致。

实操建议:

  • 基础场景用 std::atomic* 替代裸 int*,但注意 std::atomic 对象必须在共享内存内对齐且生命周期由进程共同管理
  • 复杂状态变更必须加锁:在共享内存里预留空间放 pthread_mutex_t,初始化时调用 pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED),再 pthread_mutex_init
  • 避免用 std::mutex —— 它不是进程间共享的,内部含非共享字段(如线程 ID 缓存),跨进程调用会 crash

munmap 后还用原指针会发生什么

映射解除后,该指针变成悬空指针(dangling pointer)。再次解引用(哪怕只读)大概率触发 Segmentation fault (core dumped);少数情况可能读到旧数据(页表尚未刷新、TLB 缓存未失效),但这是不可靠的运气,不是行为保证。

C++14
C++14

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

下载

更隐蔽的问题:如果进程先 munmap,又调用 shm_unlink,而另一进程还在用该地址,Linux 可能延迟回收物理页,导致读写看似正常,直到某次 page fault 才崩,复现困难。

实操建议:

  • munmap 返回成功后,立即将指针置为 nullptr,后续使用前判空
  • 不要依赖 “没立刻崩” 就认为安全;所有跨进程指针操作必须有明确的生命周期协议(例如谁创建、谁销毁、是否等待对方退出)
  • 调试时启用 AddressSanitizer(ASan),它能捕获多数 use-after-unmap 访问

Windows 上用 CreateFileMapping + MapViewOfFile,指针操作有什么差异

Win32 的 MapViewOfFile 返回也是 LPVOID(即 void*),强转规则和 Linux 一致。但关键差异在于:Windows 共享内存默认不支持进程间互斥同步原语直接嵌入——CRITICAL_SECTION 是线程级的,SRWLOCK 不支持跨进程,必须用 HANDLE 类型的命名对象(如 CreateMutex、CreateEvent)配合使用。

另一个坑:Windows 的页面保护粒度是 4KB,而 Linux 的 mmap 可设 PROT_READ/PROT_WRITE 精确控制;若在 Windows 上映射为 PAGE_READONLY,后续用 VirtualProtect 升级权限,必须确保调用方有足够权限,且所有进程视角一致。

实操建议:

  • 避免在共享内存里放 C++ 对象(含虚函数表、RTTI),Windows 的 ABI 和 vtable 布局可能与 Linux 不同,跨平台迁移时极易出错
  • 用 #ifdef _WIN32 隔离同步逻辑:Linux 用 pthread_mutex_t,Windows 用 HANDLE + WaitForSingleObject
  • 路径名注意:Windows 的 CreateFileMapping 第一个参数是文件句柄,命名共享内存用 L"Local\MyShm"(当前会话)或 L"Global\MyShm"(系统范围),别漏掉 Local\ 前缀,否则可能被当成文件路径解析

最易被忽略的是结构体填充(padding)——即使两边都用 clang/g++ 编译,若一端开了 -march=native 引入 AVX 寄存器优化,alignas(32) 可能被隐式插入,导致同样 struct 在两进程里 sizeof 不同。务必用 #pragma pack(1) 或 alignas 显式控制,并用 static_assert 校验大小和偏移。

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

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

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

下载

相关标签:

c++指针 c++ c++编程

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

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2288

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

347

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

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

精品课程

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

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

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

共0课时 | 0人学习