You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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");

修复说明

  1. 改为接收shared_ptr<Node>作为参数,既符合智能指针使用习惯,也能确保递归过程中节点不会被意外释放。
  2. 递归调用后检查返回结果,找到目标节点就立即返回,无需继续遍历。
  3. 未找到节点时返回nullptr,便于调用者判断查找是否成功。
  4. 增加当前节点检查(可选,若需要支持查找起始节点自身)。

你还可以在main函数中添加错误判断逻辑:

current_node = find(tree, "FOLDER_D");
if (!current_node) {
    std::cout << "未找到FOLDER_D" << std::endl;
    // 处理错误
}

内容的提问来源于stack exchange,提问作者Presisor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 05:05:38