Windows平台std::ostringstream 2GB容量上限问题及实现合规性咨询
Windows平台std::ostringstream 2GB容量上限问题及实现合规性咨询
最近我做了个测试,分别往std::string和std::ostringstream对象里每次写入0.5GB的数据,每一步都查询并打印它们的实际大小,结果发现了一个奇怪的跨平台差异:
Windows(64位编译)测试结果
- Step 1 | std::string size: 0.5 GB | ostringstream size: 0.5 GB
- Step 2 | std::string size: 1 GB | ostringstream size: 1 GB
- Step 3 | std::string size: 1.5 GB | ostringstream size: 1.5 GB
- Step 4 | std::string size: 2 GB | ostringstream size: 2 GB
- Step 5 | std::string size: 2.5 GB | ostringstream size: 2 GB
- Step 6 | std::string size: 3 GB | ostringstream size: 2 GB
Finished writing 3 GB to files.
其他操作系统(比如macOS + GCC/Clang)测试结果
- Step 1 | std::string size: 0.5 GB | ostringstream size: 0.5 GB
- Step 2 | std::string size: 1 GB | ostringstream size: 1 GB
- Step 3 | std::string size: 1.5 GB | ostringstream size: 1.5 GB
- Step 4 | std::string size: 2 GB | ostringstream size: 2 GB
- Step 5 | std::string size: 2.5 GB | ostringstream size: 2.5 GB
- Step 6 | std::string size: 3 GB | ostringstream size: 3 GB
Finished writing 3 GB to files.
我现在有点疑惑:微软对std::ostringstream的实现是不是不符合标准?根据我查到的所有资料,std::ostringstream应该是std::string的包装类,它的最大容量应该和std::string的最大长度一致才对。
测试源代码
stringwriter.cpp
#include <iostream> #include <fstream> #include <sstream> #include <string> #include <iomanip> constexpr std::size_t HALF_GB = 512 * 1024 * 1024; // 0.5 GB in bytes constexpr std::size_t THREE_GB = 3ULL * 1024 * 1024 * 1024; // 3 GB in bytes int main() { std::string str; std::ostringstream oss; // Block for 0.5GB, filled with 'A' std::string block(HALF_GB, 'A'); std::size_t current_size = 0; int step = 0; while (current_size < THREE_GB) { ++step; // Append to std::string str.append(block); // Append to std::ostringstream oss.write(block.data(), block.size()); // Query actual sizes std::size_t str_size = str.size(); std::size_t oss_size = oss.str().size(); current_size = str_size; // Since both should grow equally std::cout << "Step " << step << " | std::string size: " << str_size / (1024.0 * 1024 * 1024) << " GB" << " | ostringstream size: " << oss_size / (1024.0 * 1024 * 1024) << " GB" << std::endl; } // Save to disk (just write once for demonstration; in a real scenario these files would be very large) std::ofstream fout_str("string_output.bin", std::ios::binary); fout_str.write(str.data(), str.size()); fout_str.close(); std::ofstream fout_oss("oss_output.bin", std::ios::binary); std::string oss_content = oss.str(); fout_oss.write(oss_content.data(), oss_content.size()); fout_oss.close(); std::cout << "Finished writing " << (THREE_GB / (1024.0 * 1024 * 1024)) << " GB to files." << std::endl; return 0; }
CMakeLists.txt
cmake_minimum_required(VERSION 3.8) project(stringwriter CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) add_executable(stringwriter stringwriter.cpp)
内容来源于stack exchange
相关产品推荐
相关产品推荐

