使用push_back向C++ Vector添加DataFolder时原有数据损坏的解决方法
问题分析与解决方案
核心原因
你遇到的问题本质是DataFolder类的默认浅拷贝行为导致的资源失效。如果你的DataFolder类包含裸指针、动态分配内存(比如用new创建的字符串/数组),或者未正确管理的外部资源,默认拷贝构造函数只会复制指针本身,而非指针指向的实际数据。当迭代过程中的临时DataFolder对象销毁时,它占用的堆内存被释放,vector中之前存储的拷贝对象就会持有野指针,最终导致数据损坏。
修复步骤
1. 优先替换为标准库容器(最简修复)
如果类中用裸指针(比如char*)存储路径、名称这类字符串,直接换成std::string——它会自动处理深拷贝,无需手动管理内存:
class DataFolder { public: std::string path; // 替换char* path std::string name; uint64_t file_size; time_t datenum; // 其他成员与方法 };
2. 手动实现深拷贝(若必须用动态内存)
如果类依赖动态分配的内存,必须手动实现拷贝构造函数和赋值运算符重载,确保拷贝时复制实际数据而非指针:
class DataFolder { private: char* path; size_t path_len; // 其他成员 public: // 构造函数 DataFolder(const char* p) { path_len = strlen(p); path = new char[path_len + 1]; strcpy(path, p); } // 深拷贝构造函数 DataFolder(const DataFolder& other) { path_len = other.path_len; path = new char[path_len + 1]; strcpy(path, other.path); // 拷贝其他值类型成员 file_size = other.file_size; datenum = other.datenum; } // 深拷贝赋值运算符 DataFolder& operator=(const DataFolder& other) { if (this == &other) return *this; // 防止自赋值 // 释放当前对象内存 delete[] path; // 复制新数据 path_len = other.path_len; path = new char[path_len + 1]; strcpy(path, other.path); // 拷贝其他成员 file_size = other.file_size; datenum = other.datenum; return *this; } // 析构函数释放内存 ~DataFolder() { delete[] path; } };
3. 用移动语义优化(可选)
若想避免频繁深拷贝的开销,可为DataFolder添加移动构造函数和移动赋值运算符,让push_back直接转移临时对象的资源:
// 移动构造函数 DataFolder(DataFolder&& other) noexcept { path = other.path; path_len = other.path_len; // 重置原对象指针,避免析构时重复释放 other.path = nullptr; other.path_len = 0; // 移动其他成员 file_size = other.file_size; datenum = other.datenum; } // 移动赋值运算符 DataFolder& operator=(DataFolder&& other) noexcept { if (this == &other) return *this; delete[] path; path = other.path; path_len = other.path_len; other.path = nullptr; other.path_len = 0; file_size = other.file_size; datenum = other.datenum; return *this; }
调用时用std::move转移临时对象:
vector<DataFolder> folder_list; // temp_folder为临时创建的DataFolder对象 folder_list.push_back(std::move(temp_folder));
4. 确认对象生命周期
确保recursive_directory_iterator遍历过程中,创建的DataFolder对象不会提前销毁。用深拷贝或std::string的情况下,该问题会自动解决。
验证方式
修复后遍历vector,打印每个元素的路径、大小等属性,若所有元素都能正常输出,则问题解决。
内容的提问来源于stack exchange,提问作者BiggerB2008
相关产品推荐
相关产品推荐

