不能直接用std::sort对几十GB数组排序,因内存无法容纳全部数据,会触发OOM;需采用外部排序:分块读入、内存排序、写临时文件、多路归并。

为什么不能直接用 std::sort 对几十GB的数组排序
因为内存根本装不下。假设你有 100GB 的 int 数据,而物理内存只有 16GB,std::sort 会尝试把全部数据加载进内存做比较和交换——这会触发 OOM 或被系统 kill。外部排序的核心思路是「分块读入 → 内存排序 → 写临时文件 → 归并」,不依赖整体载入。
如何分块生成已排序的临时文件(run)
关键在于控制每块大小,确保单次排序不爆内存。比如限制每块最多读 512MB 数据:
- 用
std::ifstream按固定字节数(如512 * 1024 * 1024 / sizeof(int)个int)分批读入std::vector - 对每个
vector调用std::sort,然后用std::ofstream写入独立临时文件(如run_001.bin、run_002.bin) - 务必用二进制模式写入(
std::ios::binary),避免文本换行符干扰;同时记录每个 run 的长度,方便后续归并时判断 EOF
多路归并时怎么避免内存溢出
归并 N 个 run 时,若为每个 run 开一个 std::ifstream 并预读一个元素,总共只占用 N×sizeof(int) 字节,完全可控。但要注意:
- 不要用
std::priority_queue存整个 buffer,只存「当前最小值 + 对应文件句柄 + 下一个偏移」三元组 - 每次从堆顶取出最小元素后,立即从对应文件再读一个新元素(如果还有);若该 run 已空,则从堆中移除
- 归并输出也必须用二进制写入,且建议用
setvbuf设置大缓冲区(如 1MB),减少系统调用开销
实际跑起来卡在 I/O 或归并不对?检查这几处
常见故障点不在算法逻辑,而在底层 I/O 控制:
立即学习“C++免费学习笔记(深入)”;
- 临时文件路径是否可写?磁盘空间是否足够?归并阶段需要 ≈ 2×输入数据的空闲空间(输入 + 输出)
- 是否关闭了所有
ifstream?忘了.close()可能导致 Linux 下“too many open files”错误(EMFILE) - 二进制读写是否严格对齐?例如用
read(reinterpret_cast<char>(&x), sizeof(x))</char>,而不是>>流提取符(后者会解析格式,破坏二进制一致性) - 跨平台时注意
off_t和size_t在 32 位环境可能溢出,大型文件操作优先用std::ifstream::seekg配合std::streamoff
真正麻烦的是错误恢复:某个 run 文件损坏或提前截断,归并过程不会报明显异常,只会静默输出错序结果。加校验和或分段 checksum 是上线前必须补的环节。


















