讲师中心 微信公众号
AI工具推荐 视频效率加速

c++怎么将复杂的std::map数据存入二进制【实战】

千雪君_8499

千雪君_8499

发布时间:2026-04-05 19:46:36

|

600人浏览过

|

来源于php中文网

原创

不能直接fwrite,因为std::map内存布局含指针、不连续、不可移植;必须手动序列化逻辑数据:先写大小,再逐对写key长度+内容、value长度+元素。

c++怎么将复杂的std::map<string, vector<int>>数据存入二进制【实战】

std::map> 二进制序列化为什么不能直接 fwrite?

直接对 std::map 对象调用 fwrite 会崩溃或产生乱码,因为 std::map 是红黑树实现,内部包含指针(如 _M_header, _M_left 等),内存布局不连续、不可移植。vector 同样有指针成员(_M_start, _M_finish, _M_end_of_storage),其数据在堆上,sizeof(vector<int>) ≈ 24 字节(64 位),但实际内容不在对象内。

关键点:你只能序列化「逻辑数据」,不是「内存镜像」。

手动序列化:先 flatten 再写入文件

核心思路是把嵌套结构拆成线性字节流:先写 map 大小 → 遍历每对 key/value → 先写 key 长度 + key 字符串 → 再写 value.size() + 所有 int 值。

实操建议:

立即学习“C++免费学习笔记(深入)”;

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
  • std::string 序列化必须带长度前缀(否则读取时无法知道字符串在哪结束)
  • vector<int> 同理:先写 size_t 长度,再写 data() 指向的原始 int 数组
  • 所有整数统一用固定宽度类型(如 uint32_t)避免平台差异;sizeof(size_t) 在 32/64 位系统不同
  • 用 std::ofstream::write 配合 reinterpret_cast<const char*>() 写原始字节
#include <fstream>
#include <map>
#include <string>
#include <vector>
#include <cstdint>
<p>void save_map_binary(const std::map<std::string, std::vector<int>>& m, const char<em> path) {
std::ofstream f(path, std::ios::binary);
uint32_t size = static_cast<uint32_t>(m.size());
f.write(reinterpret_cast<const char</em>>(&size), sizeof(size));</p><pre class='brush:php;toolbar:false;'>for (const auto& [k, v] : m) {
    uint32_t klen = static_cast<uint32_t>(k.size());
    f.write(reinterpret_cast<const char*>(&klen), sizeof(klen));
    f.write(k.data(), klen);

    uint32_t vlen = static_cast<uint32_t>(v.size());
    f.write(reinterpret_cast<const char*>(&vlen), sizeof(vlen));
    if (!v.empty()) {
        f.write(reinterpret_cast<const char*>(v.data()), vlen * sizeof(int));
    }
}

}

反序列化时最容易踩的三个坑

读取顺序错一位、类型宽度不一致、未检查文件读取是否成功 —— 这三者足以让程序静默读错数据或崩溃。

  • 务必逐字段校验返回值:if (!f.read(...)) { /* error */ },不要只靠 eof()
  • 读 uint32_t 时用 reinterpret_cast<char*>(&var),别用 &var 直接传(可能因对齐或别名规则出问题)
  • std::string 构造时用 std::string(buf, len),别用 std::string(buf)(后者会找 \0,而你的 key 可能含 \0)
  • 如果 map key 是中文或 UTF-8,没问题 —— 你存的就是原始字节,只要读写编码一致即可

要不要用 Protocol Buffers 或 cereal?

如果你的项目已引入构建复杂度容忍度高,且未来要跨语言或加字段,默认推荐 cereal(header-only,支持 STL 容器);但若只是临时导出给另一个 C++ 程序读,手写上面那段 30 行代码更轻量、无依赖、完全可控。

注意:cereal 默认用 std::ofstream::binary,但它的 JSON 归档模式不适用 —— 必须显式用 BinaryOutputArchive;另外它对 std::map<K,V> 的序列化默认要求 K 可默认构造,std::string 满足,但自定义 key 类型需留意。

二进制序列化的真正难点从来不在“怎么写”,而在“怎么保证每次读都和写时的内存解释完全一致”——字节序、对齐、类型尺寸、容器内部结构,漏掉任意一环,数据就不可逆损坏。

相关文章

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

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

下载

相关标签:

c++

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

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
json数据格式
json数据格式

JSON是一种轻量级的数据交换格式。本专题为大家带来json数据格式相关文章,帮助大家解决问题。

1975

2023.08.07

json是什么
json是什么

JSON是一种轻量级的数据交换格式,具有简洁、易读、跨平台和语言的特点,JSON数据是通过键值对的方式进行组织,其中键是字符串,值可以是字符串、数值、布尔值、数组、对象或者null,在Web开发、数据交换和配置文件等方面得到广泛应用。本专题为大家提供json相关的文章、下载、课程内容,供大家免费下载体验。

2702

2023.08.23

jquery怎么操作json
jquery怎么操作json

操作的方法有:1、“$.parseJSON(jsonString)”2、“$.getJSON(url, data, success)”;3、“$.each(obj, callback)”;4、“$.ajax()”。更多jquery怎么操作json的详细内容,可以访问本专题下面的文章。

936

2023.10.13

go语言处理json数据方法
go语言处理json数据方法

本专题整合了go语言中处理json数据方法,阅读专题下面的文章了解更多详细内容。

3019

2025.09.10

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

5279

2023.08.02

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

889

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2420

2023.10.25

c语言const用法
c语言const用法

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

1958

2023.09.20

Buffalo框架数据库开发全教程
Buffalo框架数据库开发全教程

本专题围绕Buffalo框架数据库开发,讲解database.yml多环境配置、soda与fizz迁移生成回滚、模型结构体标签、增删改查与条件查询、一对多与多对多关联、数据校验、回调钩子、事务处理及原生SQL执行能力。

120

2026.09.23

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn