0

I've written a binary tree-like structure, but I've been getting stack-overflow errors in some of my stress tests. I've reduced the error-causing code down to the following: struct Node { index: usize, right: Option>, }

struct BoxedTree {
    root: Option<Box<Node>>,
}

fn build_degenerate() {
    let mut t = BoxedTree {
        root: Some(Box::new(Node {
            index: 0,
            right: None,
        })),
    };
    let mut n = t.root.as_mut().unwrap();
    for i in 1..50000 {
        let cur = n;
        let p = &mut cur.right;
        *p = Some(Box::new(Node {
            index: i,
            right: None,
        }));
        n = p.as_mut().unwrap();
    }
    println!("{}", n.index);
}

fn main() {
    build_degenerate();
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn mytest() {
        build_degenerate();
    }
}

Running cargo test gives me:

running 1 test

thread 'tests::mytest' has overflowed its stack
fatal runtime error: stack overflow
error: process didn't exit successfully: ...

I don't understand how this code could be causing a stack overflow, as all data seems to be allocated on the heap, and there is no recursion.

Even stranger, this code causes an overflow when I run cargo test, but not when I run cargo run, even though mytest and main call the same code.

What's going wrong here?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Isaac
  • 3,586
  • 1
  • 18
  • 20
  • 1
    I believe your question is answered by the answers of [Do we need to manually create a destructor for a linked list?](https://stackoverflow.com/q/38147453/155423), [Why does my iterative implementation of drop for a linked list still cause a stack overflow?](https://stackoverflow.com/q/47051923/155423) and [cargo test --release causes a stack overflow. Why doesn't cargo bench?](https://stackoverflow.com/q/42955243/155423). If you disagree, please [edit] your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Jul 01 '18 at 03:20
  • 1
    TL;DR: "and there is no recursion" is a lie and tests have a smaller stack size. – Shepmaster Jul 01 '18 at 03:20
  • Ah, so the default destructor is recursive; that makes perfect sense, thank you. – Isaac Jul 01 '18 at 04:15

0 Answers0