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

C++ 返回二级指针实现二叉树按层取节点内存异常问题求助

问题根因与修复方案

核心错误点

你代码的问题来自三个典型的C++内存操作错误:

  • 缓冲区溢出:getLevel函数中仅用new Node分配了1个Node大小的堆内存,当层级节点数超过1时,写入操作直接越界访问未分配内存,内容自然不可控
  • 返回局部栈变量地址:emptyNode是getLevel函数栈上的局部指针变量,函数退出后栈空间会被系统回收,你返回的&emptyNode属于野指针,后续访问的内容完全不可控
  • 指针偏移逻辑混淆:递归结束后你回退指针得到的是堆数组的首地址,但返回的是栈上指针变量的地址,主函数操作的*emptyNode根本不是你分配的堆数组地址

修复方案

1. 调整getLevel接口与内存分配逻辑

这里推荐把返回值从Node**简化为Node*,直接返回堆数组的首地址,更符合使用习惯:

Node* getLevel(int level, int * size) {
    // 二叉树第level层最多存在2^level个节点,提前分配足够空间
    int maxLevelNodeCnt = 1 << level;
    Node* resultArr = new Node[maxLevelNodeCnt];
    Node* writePtr = resultArr;
    *size = 0;
    getTreeLevel(level, size, root, &writePtr);
    cout << "There are " << *size << " nodes in the level" << endl;
    return resultArr;
}

getTreeLevel原有逻辑可以完全复用,不需要修改。

2. 主函数调用逻辑修正

int size;
Node* levelNodes = tree.getLevel(0, &size);
for (int i = 0; i < size; i++) {
    // 直接用下标访问数组,逻辑更清晰
    cout << levelNodes[i].val << " - ";
}
cout << endl;
// 内存使用完毕后手动释放,避免内存泄漏
delete[] levelNodes;

优化建议

如果不想手动计算层级最大节点数、手动管理内存,可以用std::vector替代原生数组,代码更安全:

#include <vector>
#include <functional>
using namespace std;

vector<Node> getLevel(int level) {
    vector<Node> res;
    // 重写遍历逻辑,直接往vector里push_back节点即可
    function<void(int, Node*)> dfs = [&](int curLevel, Node* cur) {
        if (!cur) return;
        if (curLevel == 0) {
            res.push_back(*cur);
            return;
        }
        dfs(curLevel-1, cur->left);
        dfs(curLevel-1, cur->right);
    };
    dfs(level, root);
    cout << "There are " << res.size() << " nodes in the level" << endl;
    return res;
}

主函数调用更简单:

auto levelNodes = tree.getLevel(0);
for (auto& node : levelNodes) {
    cout << node.val << " - ";
}
cout << endl;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 22:39:04