如何用std::get_temporary_buffer读取文件并填充myStruct向量?
当然可以用 std::get_temporary_buffer 来实现你的需求!不过先给你提个醒:这个函数在C17标准里已经被标记为弃用了,如果你使用的是较新的C版本,更推荐用std::unique_ptr配合手动内存管理或者直接利用vector的预留空间来做临时存储。但既然你明确问了这个方法,我就详细给你拆解实现步骤,同时也会提一下替代方案。
首先,先明确你的核心需求:把文件读取和vector插入逻辑分开,用临时缓冲区暂存数据。那我们的思路就是:先写一个读取函数,专门负责从文件拉取数据到临时缓冲区;再写一个插入函数,把缓冲区里的内容转移到vector中,最后释放临时内存。
先沿用你的结构体定义:
struct myStruct { int i,j; double x,y,z,f; myStruct(int i_, int j_, double x_, double y_, double z_, double f_): i(i_),j(j_),x(x_),y(y_),z(z_),f(f_) {} };
这里注意到你的结构体有6个成员,但文件只有5列数据——我假设文件的5列对应i,j,x,y,z,f用默认值(比如0.0),你可以根据实际需求调整这个映射关系。
第一步:实现读取到临时缓冲区的函数
这个函数的职责是打开文件、统计行数(预估需要的缓冲区大小)、分配临时内存、读取数据并构造myStruct对象到缓冲区里:
#include <iostream> #include <fstream> #include <vector> #include <memory> #include <string> std::pair<myStruct*, std::ptrdiff_t> read_to_temp_buffer(const std::string& filename) { std::ifstream file(filename); if (!file.is_open()) { std::cerr << "Error: Could not open file " << filename << std::endl; return {nullptr, 0}; } // 先统计文件行数,预估需要的元素数量 std::ptrdiff_t line_count = 0; std::string dummy_line; while (std::getline(file, dummy_line)) { ++line_count; } // 重置文件指针到开头,准备读取数据 file.clear(); file.seekg(std::ios::beg); // 申请临时缓冲区:get_temporary_buffer返回(指针,实际分配的最大元素数) auto temp_buffer = std::get_temporary_buffer<myStruct>(line_count); if (temp_buffer.first == nullptr) { std::cerr << "Error: Failed to allocate temporary buffer" << std::endl; return {nullptr, 0}; } // 读取数据并构造myStruct对象到缓冲区(用placement new,因为缓冲区内存未初始化) std::ptrdiff_t inserted_count = 0; int i, j; double x, y, z; while (file >> i >> j >> x >> y >> z && inserted_count < temp_buffer.second) { // 在缓冲区的指定位置构造对象 new (&temp_buffer.first[inserted_count]) myStruct(i, j, x, y, z, 0.0); ++inserted_count; } // 返回缓冲区指针和实际读取到的元素数量 return {temp_buffer.first, inserted_count}; }
第二步:实现将缓冲区数据插入vector的函数
这个函数负责把临时缓冲区里的元素转移到vector,同时清理临时内存:
void insert_to_vector(std::vector<myStruct>& target_vec, myStruct* temp_buf, std::ptrdiff_t elem_count) { if (!temp_buf || elem_count <= 0) { return; } // 先给vector预留足够空间,避免多次扩容 target_vec.reserve(target_vec.size() + elem_count); // 逐个将缓冲区的元素移动到vector(或者拷贝,根据你的需求) for (std::ptrdiff_t idx = 0; idx < elem_count; ++idx) { target_vec.emplace_back(std::move(temp_buf[idx])); // 手动调用缓冲区中对象的析构函数,因为是placement new构造的 temp_buf[idx].~myStruct(); } // 释放临时缓冲区的内存 std::return_temporary_buffer(temp_buf); }
第三步:主函数调用示例
把这两个函数整合起来,完成整个流程:
int main() { std::vector<myStruct> my_data_vec; // 读取数据到临时缓冲区 auto read_result = read_to_temp_buffer("your_data_file.txt"); myStruct* temp_buf = read_result.first; std::ptrdiff_t read_count = read_result.second; // 如果读取成功,就插入到vector if (temp_buf && read_count > 0) { insert_to_vector(my_data_vec, temp_buf, read_count); std::cout << "Successfully loaded " << read_count << " elements into vector" << std::endl; } // 验证结果(可选) for (const auto& elem : my_data_vec) { std::cout << elem.i << ", " << elem.j << ", " << elem.x << ", " << elem.y << ", " << elem.z << ", " << elem.f << "\n"; } return 0; }
关键注意事项
std::get_temporary_buffer的限制:它返回的缓冲区大小可能比你请求的小(比如内存不足时),所以读取数据时一定要检查inserted_count是否小于temp_buffer.second,避免越界访问。- 内存管理细节:因为临时缓冲区的内存是未初始化的,必须用
placement new构造对象;用完之后要手动调用析构函数,再用std::return_temporary_buffer释放内存——如果跳过这步,会导致内存泄漏或者对象析构不完整。 - C++17+替代方案:既然
std::get_temporary_buffer被弃用,你可以用std::unique_ptr<myStruct[]>来替代临时缓冲区,这样内存会自动管理,不需要手动调用return_temporary_buffer,示例如下:
// 替代get_temporary_buffer的方式 std::unique_ptr<myStruct[]> temp_buf = std::make_unique<myStruct[]>(line_count); // 不过因为myStruct没有默认构造函数,你还是需要用placement new来构造对象,和之前逻辑类似
内容的提问来源于stack exchange,提问作者user12008861
相关产品推荐
相关产品推荐

