结构体中vector动态分配读取大文件时崩溃问题求助
解决C++读取double文件时的
corrupted size vs. prev_size崩溃问题 你的代码崩溃的核心原因是错误操作了std::vector的内存结构,下面我会一步步拆解问题,再给出修复后的高效方案:
问题定位
reserve不改变vector的实际元素数量
你调用path->trivial_vector.reserve(buffer.size() / sizeof(double))只是给vector预留了内存空间,但vector的size()仍然是0。这时候直接用&path->trivial_vector[0]访问内存属于未定义行为——vector没有实际元素,首地址指向的内存未初始化,memcpy往这里写数据会直接破坏vector的内部管理结构,导致内存崩溃。不必要的指针引用参数
函数参数PathStruct *&path是指针的引用,但你在函数里并没有修改path指针本身(比如重新分配内存),用普通的PathStruct *path就足够了,虽然这不是崩溃的直接原因,但会增加代码复杂度。未校验文件字节数合法性
如果文件总字节数不是sizeof(double)的整数倍,buffer.size() / sizeof(double)会得到错误的元素数量,后续的memcpy会导致内存越界。
修复后的高效代码
下面的版本解决了所有问题,同时还减少了一次内存拷贝,完全符合你降低开销的需求:
#include <fstream> #include <vector> #include <cstring> #include <memory> struct PathStruct { std::vector<double> trivial_vector; }; bool getFileContent(PathStruct *path) { std::ifstream file("simplePath.txt", std::ios::binary); if (!file.is_open()) { return false; } // 获取文件总大小 file.seekg(0, std::ios::end); const std::streampos fileSize = file.tellg(); file.seekg(0, std::ios::beg); // 校验文件大小是否为double的整数倍,避免数据截断 if (fileSize % sizeof(double) != 0) { return false; } const size_t elementCount = static_cast<size_t>(fileSize) / sizeof(double); // 直接分配vector内存并读取文件,跳过中间buffer的拷贝 path->trivial_vector.resize(elementCount); file.read(reinterpret_cast<char*>(path->trivial_vector.data()), fileSize); // 校验是否完整读取了文件内容 return file.good(); }; int main(int argc, char **argv) { // 用智能指针管理内存,避免裸指针泄漏 std::unique_ptr<PathStruct> path = std::make_unique<PathStruct>(); const bool result = getFileContent(path.get()); return result ? 0 : 1; }
额外优化建议
- 如果你的文件是文本格式(不是二进制存储的double),不能用二进制读取的方式,这时候可以用
std::istream_iterator直接读取转换,代码更安全:bool getFileContent(PathStruct *path) { std::ifstream file("simplePath.txt"); if (!file.is_open()) return false; std::copy(std::istream_iterator<double>(file), std::istream_iterator<double>(), std::back_inserter(path->trivial_vector)); return file.eof(); // 确认是正常读取到文件末尾 }
内容的提问来源于stack exchange,提问作者kmaqueta
相关产品推荐
相关产品推荐

