构造大树时“线程'
'已溢出其堆栈”

2024-01-21

我实现了一个树结构:

use std::collections::VecDeque;
use std::rc::{Rc, Weak};
use std::cell::RefCell;

struct A {
    children: Option<VecDeque<Rc<RefCell<A>>>>
}

// I got thread '<main>' has overflowed its stack
fn main(){
    let mut tree_stack: VecDeque<Rc<RefCell<A>>> = VecDeque::new();

    // when num is 1000, everything works
    for i in 0..100000 {
        tree_stack.push_back(Rc::new(RefCell::new(A {children: None})));
    }

    println!("{:?}", "reach here means we are not out of mem");
    loop {
        if tree_stack.len() == 1 {break;}

        let mut new_tree_node = Rc::new(RefCell::new(A {children: None}));
        let mut tree_node_children: VecDeque<Rc<RefCell<A>>> = VecDeque::new();

        // combine last two nodes to one new node
        match tree_stack.pop_back() {
            Some(x) => {
                tree_node_children.push_front(x);
            },
            None => {}
        } 
        match tree_stack.pop_back() {
            Some(x) => {
                tree_node_children.push_front(x);
            },
            None => {}
        } 

        new_tree_node.borrow_mut().children = Some(tree_node_children);
        tree_stack.push_back(new_tree_node);
    }
}

婴儿围栏链接 http://is.gd/0RF6SR

但它崩溃了

thread '<main>' has overflowed its stack

我该如何解决这个问题?


您遇到的问题是因为您有一个巨大的节点链表。当该列表被删除时,第一个元素首先尝试释放结构体的所有成员。这意味着第二个元素执行相同的操作,依此类推,直到列表末尾。这意味着您将拥有一个与列表中元素数量成正比的调用堆栈!

这是一个小复制品:

struct A {
    children: Option<Box<A>>
}

fn main() {
    let mut list = A { children: None };

    for _ in 0..1_000_000 {
        list = A { children: Some(Box::new(list)) };
    }
}

修复方法如下:

impl Drop for A {
    fn drop(&mut self) {
        if let Some(mut child) = self.children.take() {
            while let Some(next) = child.children.take() {
                child = next;
            }
        }
    }
}

此代码使用迭代覆盖默认的递归删除实现。它撕裂了children从节点中取出,用终端项替换它(None)。然后它允许节点正常删除,但不会有递归调用。

代码有点复杂,因为我们不能放弃自己,所以我们需要跳一段两步舞来忽略第一个项目,然后吃掉所有的孩子。

也可以看看:

  • 如何为结构的可变引用中的字段交换新值? https://stackoverflow.com/q/27098694/155423
  • 如何移出作为选项的结构体字段? https://stackoverflow.com/q/52031002/155423
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

构造大树时“线程'
'已溢出其堆栈” 的相关文章

随机推荐

  • Android:带有自定义标题的圆角 TextView XML 布局

    我想使用圆角和自定义标头为我的 TextView 创建自定义 XML 布局 例如本示例 我发现这很有用的链接 http www donnfelker com android rounded corners with a beveldrop
  • Rails:我的应用程序如何判断它是在 MRI 还是 JRuby 中运行?

    In a 上一个问题 https stackoverflow com questions 7802678 porting a ruby rails mri app to jruby 我问如何告诉我的 Gemfile 是采用 JRuby 相关
  • 是否有任何理由在同一字段上同时使用主键和唯一键?

    我正在分析 Oracle 数据库设计 我很困惑地看到同一字段上同时存在唯一键和主键 这些唯一主键对在所有表上一致创建 我认为没有理由这样做 如果我无论如何都有主键 是否有充分的理由在同一字段上创建额外的唯一键 对于解析多对多的表 通常有一个
  • 此操作不支持一致性级别 LOCAL_ONE。支持的一致性级别有:LOCAL_QUORUM

    我正在使用 AWS keyspaces 并尝试从 C 插入数据 但收到此错误 此操作不支持一致性级别 LOCAL ONE 支持的一致性级别是 LOCAL QUORUM 有人可以帮忙吗 AWS密钥空间 CREATE KEYSPACE IF N
  • 多次限制获得公共服务

    我有这样的情况 想象一下有一个公共 REST 服务 我们不希望某人能够在短时间内多次访问此服务 因为他们将能够阻止我们的数据库 我认为本质上是 DDOS 攻击 有没有办法有效防范此类攻击 我们使用的技术是 Spring Spring Sec
  • 如何在不使用 Mapbox 的情况下使用 OpenStreetMap?

    我想使用 OSM OpenStreetMap 数据 但有一种方法 Mapbox 可以使用吗 如果有其他解决方案可以在不使用 MapBox 的情况下使用 OSM OpenStreetMap 那对我会有帮助 由于这是用 Swift 标记的 我假
  • 使用 django-storages 和 S3boto 后端保存到 S3 时如何设置“Content-Type”?

    我在用django storages with s3boto作为后端 我有一个桶 里面有两个文件夹 一个用于static和一个用于media 我使用以下方法实现了这一点django s3 folder storage 除了使用模型保存到 S
  • Visual Studio 2010 编译 C 代码

    我有以下代码片段 这是 Visual Studio 2010 中的一个 C 文件 如果我尝试使用以下行编译它 int hello 10 注释掉它会编译得很好 如果我评论其中的那一行将无法编译 我是否遗漏了某些内容 或者我不应该使用 Visu
  • 为偶数和奇数 div 添加不同的类

    我有一段 PHP 代码 如下所示 flag false if empty links echo h1 You have no uploaded images h1 br foreach links as link extension sub
  • 如何设置工作项的必填字段和默认值

    我正在为我的项目使用 Visual Studio Team Services 并通过网络访问它 我正在使用 Scrum 模板 我试图弄清楚如何设置任务字段的默认值 例如 对于任务的 活动 字段 我希望将其设为必填字段 并在每次添加新任务时将
  • 如何隐藏按钮轮廓

    我的这个页面有很多按钮 https jsfiddle net Android272 c150305z https jsfiddle net Android272 c150305z 我已经尝试了以下代码的每种组合 但没有任何方法可以摆脱轮廓
  • 具有动态维度的数组的子集部分

    我想对一个具有动态维数 k 的数组进行子集化 举个例子 A lt array 1 3 4 dim c 3 3 3 3 因为尺寸可能会有所不同 此处未显示 所以我不能简单地定义 a b c d 并通过以下方式进行查询 a lt 1 2 b l
  • 调试时 Epplus Save()、SaveAs() 等方法运行速度非常慢

    环境 Windows 10 Visual Studio 2017 netcore2 0 调试版本 在调试时使用 Epplus 4 1 1 保存 Excel 文件时 保存操作花费的时间比我预期的要长得多 这是使用 调试 gt 开始调试 运行时
  • 将每个 R for 循环迭代保存在新列表中

    我正在使用dataprepSynth 包的功能 参见https cran r project org web packages Synth Synth pdf https cran r project org web packages Sy
  • 算法优化[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 这里是link https www
  • 将参数传递给 Laravel 作业不起作用

    我之前读过这个问题的解决方案 但似乎我做错了其他事情 这就是我问的原因 通常解决方案是将参数添加到类的主体以及 construct 方法中 但甚至这样做它不起作用
  • 释放R中的内存

    在 R 中 我尝试将几组时间序列数据组合并转换为 xtshttp www truefx com page downloads http www truefx com page downloads但是 这些文件很大并且有很多文件 因此这导致我
  • 正确记录日志

    所以我的问题是关于日志记录 以及如何处理可能影响您的代码和运行时行为的日志语句 日志文件 每个程序都应该编写这些文件以正确解决问题 但如何正确执行呢 大多数日志语句的获取成本非常高 因为它们应该提供有用的信息 并且即使完全禁用日志记录 它们
  • 了解 Lambda 闭包类型如何删除默认构造函数

    从5 1 2开始 19 与 lambda 表达式关联的闭包类型有一个已删除的 8 4 3 默认构造函数和一个被删除的 复制赋值运算符 它有一个隐式声明的复制构造函数 12 8 并且可能有一个隐式声明的 移动构造函数 12 8 注意 复制 移
  • '已溢出其堆栈”' aria-label='构造大树时“线程'
    '已溢出其堆栈”'> 构造大树时“线程'
    '已溢出其堆栈”

    我实现了一个树结构 use std collections VecDeque use std rc Rc Weak use std cell RefCell struct A children Option