C++在Colony类内初始化Node实例触发段错误的修复方法
问题原因
段错误由两个核心问题导致:
- 直接触发崩溃的原因:
Node start创建后,成员coords是长度为0的空vector,此时直接用[0]/[1]/[2]下标访问赋值属于越界内存访问,是C++中的未定义行为,会直接触发段错误。vector的下标运算符不会自动扩容,只能访问已经存在的元素。 - 隐藏的设计缺陷:
Node类中定义了vector<Node> parent、vector<Node> childList两个成员,属于值类型的递归包含,C++无法计算这种类型的确定内存大小,后续节点拷贝、插入vector时会触发无限递归拷贝,哪怕修了越界问题,后续运行也会出现内存溢出、崩溃的问题。
修复步骤
- 修复coords越界访问问题,两种方案二选一即可:
- 方案1:先给coords分配对应长度再赋值
void run() { Node start; start.coords.resize(3); // 先分配3个double的存储空间 start.coords[0] = 100.0; start.coords[1] = 100.0; start.coords[2] = 100.0; nodelist.push_back(start); }- 方案2:用push_back逐次追加坐标值,不需要提前分配空间
void run() { Node start; start.coords.push_back(100.0); start.coords.push_back(100.0); start.coords.push_back(100.0); nodelist.push_back(start); } - 修复Node类递归包含的设计缺陷
你的所有Node实例都存在Colony类的nodelist容器里,最稳妥的方式是存节点在nodelist中的索引,不要直接存Node值对象:class Node { public: std::vector<double> coords; int parent_idx = -1; // 根节点父索引设为-1表示无父节点 std::vector<int> child_idx_list; // 存储所有子节点在nodelist中的索引 std::vector<Attract> closestAtts; };不建议用裸指针关联节点,容易出现野指针、内存泄漏问题,索引方案和你现有代码结构适配成本最低,稳定性更高。
内容的提问来源于stack exchange,提问作者destroyer806
相关产品推荐
相关产品推荐

