动态Subject对象数组拷贝出现段错误,求原因及解决方法
分析段错误原因及修复方案
让我帮你拆解这段代码里的问题,其中数组越界是导致段错误的核心原因:
1. 笔误导致的文件流变量错误
你代码里写了while (fin >> subject),但实际定义的文件流对象是input,这个笔误要么会引发编译错误,要么运行时因为访问未定义变量直接崩溃,得先把fin改成input。
2. 错误的扩容逻辑触发数组越界
这是段错误的根本原因:
- 初始时
size=1,index=0,数组array只有1个元素的存储空间。 - 第一次循环读取元素后,你立刻创建了一个和原数组大小相同(
size=1)的temp数组,复制完元素后把size改成2、index加1变成1。 - 这时候
array指向的数组仍然只有1个元素的空间,但index已经是1了,下一次循环直接访问array[1]就触发了数组越界访问,直接导致段错误。
正确的逻辑应该是:当index等于当前数组的size时(也就是数组存满时),再进行扩容,确保新元素有足够的存储空间。
修复后的代码
我调整了逻辑,还增加了一些健壮性检查,确保代码稳定运行:
#include <iostream> #include <fstream> #include <string> // 补充Subject类的定义,方便代码编译运行 class Subject { private: std::string subjectName; std::string subjectId; public: void set_subject(const std::string& name) { subjectName = name; } void set_id(const std::string& id) { subjectId = id; } std::string get_subject() const { return subjectName; } std::string get_id() const { return subjectId; } }; int main (int argc, char** argv) { std::ifstream input("subjects.txt"); // 检查文件是否成功打开,避免后续读取失败 if (!input.is_open()) { std::cerr << "Error: 无法打开subjects.txt文件" << std::endl; return 1; } std::string subject; std::string id; int index = 0; int size = 1; Subject *array = new Subject[size]; // 一次读取一行的两个字段,逻辑更清晰 while (input >> subject >> id) { // 数组存满时扩容,用2倍扩容提升效率 if (index == size) { int new_size = size * 2; Subject *temp = new Subject[new_size]; // 复制原有元素 for (int i = 0; i < size; i++) { temp[i].set_subject(array[i].get_subject()); temp[i].set_id(array[i].get_id()); } delete [] array; array = temp; size = new_size; } // 给当前元素赋值 array[index].set_subject(subject); array[index].set_id(id); index++; } // 释放动态分配的内存,避免内存泄漏 delete [] array; input.close(); return 0; }
额外建议:用std::vector替代手动动态数组
在C++中,手动管理动态数组很容易出错,推荐使用标准库的std::vector,它会自动处理扩容和内存管理,代码更简洁安全:
#include <iostream> #include <fstream> #include <string> #include <vector> class Subject { private: std::string subjectName; std::string subjectId; public: void set_subject(const std::string& name) { subjectName = name; } void set_id(const std::string& id) { subjectId = id; } std::string get_subject() const { return subjectName; } std::string get_id() const { return subjectId; } }; int main (int argc, char** argv) { std::ifstream input("subjects.txt"); if (!input.is_open()) { std::cerr << "Error: 无法打开subjects.txt文件" << std::endl; return 1; } std::string subject; std::string id; std::vector<Subject> subjects; while (input >> subject >> id) { Subject subj; subj.set_subject(subject); subj.set_id(id); subjects.push_back(subj); // 自动扩容,无需手动处理内存 } input.close(); return 0; }
这样就彻底避免了手动操作动态数组可能出现的越界、内存泄漏等问题。
内容的提问来源于stack exchange,提问作者nc052
相关产品推荐
相关产品推荐

