C++文件系统树find函数二次调用未遍历所有子节点问题排查
文件系统树查找函数异常问题
我正在实现一个文件系统树,每个节点包含名称、大小、类型(文件或目录)、父节点(supernode)和子节点(subnode),节点类型定义如下结构体:
struct Node { std::string name; std::string type; int size; std::vector<std::shared_ptr<Node>> subnodes; std::weak_ptr<Node> supernode; };
通过以下函数初始化节点:
auto add_node(std::string a_name, std::string a_type, int a_size, std::weak_ptr<Node> a_supernode) -> std::shared_ptr<Node> { Node temporary_node; temporary_node.name = a_name; temporary_node.type = a_type; temporary_node.size = a_size; temporary_node.supernode = a_supernode; return std::make_shared<Node> ( temporary_node ); }
我编写了find()函数遍历树查找特定节点,找到后返回该节点:
auto find(const Node& node, std::string target) -> std::shared_ptr<Node> { auto identifier = std::make_shared<Node> (Node {}); for (const auto& itr : node.subnodes) { if(itr -> name == target) { identifier = itr; break; } else { find(*itr, target); } } return identifier; }
在main函数中,我创建了根节点tree并构建文件系统节点:
auto main() -> int { auto tree = std::make_shared<Node> ( Node { "/" }); tree -> type = "root"; auto current_node = tree; std::shared_ptr<Node> new_node = add_node("FOLDER_A", "directory", 0, current_node); current_node -> subnodes.push_back(new_node); std::shared_ptr<Node> new_node1 = add_node("FOLDER_B", "directory", 0, current_node); current_node -> subnodes.push_back(new_node1); current_node = find(*tree, "FOLDER_A"); std::shared_ptr<Node> new_node2 = add_node("FOLDER_C", "directory", 0, current_node); current_node -> subnodes.push_back(new_node2); std::shared_ptr<Node> new_node3 = add_node("FOLDER_D", "directory", 0, current_node); current_node -> subnodes.push_back(new_node3); current_node = find(*tree, "FOLDER_D"); return 0; }
引入的头文件如下:
#include <vector> #include <string> #include <memory> #include <iostream> #include <fstream> #include <functional>
节点初始化正常,但第二次调用find()函数时,它未遍历所有子节点就直接返回空节点。奇怪的是第一次调用find()能成功找到FOLDER_A并修改current_node。我期望find()能遍历所有节点找到存在的FOLDER_D,但第二次调用时for循环未完整执行,导致current_node未更新,请问是否是指针使用存在问题?
问题分析与修复
你的find函数存在两个核心问题:
- 递归调用结果未处理:递归调用
find(*itr, target)时,没有接收返回结果。当目标节点在子节点的子树中时,递归找到的节点无法传递回上层函数,最终上层返回的是初始化的空节点。 - 默认返回空节点不合理:一开始就创建空的
shared_ptr<Node>作为默认返回值,即使没找到节点也会返回无效实例,而非空指针,容易混淆查找结果。
修复后的find函数:
auto find(const std::shared_ptr<Node>& node, const std::string& target) -> std::shared_ptr<Node> { // 可选:检查当前节点是否为目标 if (node->name == target) { return node; } for (const auto& subnode : node->subnodes) { auto result = find(subnode, target); if (result != nullptr) { return result; } } // 未找到返回空指针 return nullptr; }
同时,main函数中调用find的地方需要调整为传入shared_ptr而非引用:
current_node = find(tree, "FOLDER_A"); // ... current_node = find(tree, "FOLDER_D");
修复说明
- 改为接收
shared_ptr<Node>作为参数,既符合智能指针使用习惯,也能确保递归过程中节点不会被意外释放。 - 递归调用后检查返回结果,找到目标节点就立即返回,无需继续遍历。
- 未找到节点时返回
nullptr,便于调用者判断查找是否成功。 - 增加当前节点检查(可选,若需要支持查找起始节点自身)。
你还可以在main函数中添加错误判断逻辑:
current_node = find(tree, "FOLDER_D"); if (!current_node) { std::cout << "未找到FOLDER_D" << std::endl; // 处理错误 }
内容的提问来源于stack exchange,提问作者Presisor
相关产品推荐
相关产品推荐

