Stack overflow occurs when calling drop

Original

Can a function in Rust push arbitrary amount of data onto stack?

I think it's possible to do in asm, but for some reason I imagined that all functions in C++ and Rust take fixed amount of space in stack, not larger than amount sum of all local variables. However I have a function that doesn't use any recursion, but has a for loop that drains a channel and constructs Box for each(in detail: executes incoming vulkan command buffers by joining them to the main gpufuture and boxes it to discard the concrete type). If the main blocks for few seconds and messages accumulate in the channel, the function overflows. Setting channel size fixed the issue.

Please suggest a better title.

Original

Minimal example:

struct Node {
    val: i32,
    next: Option<Box<Node>>,
}

impl Node {
    fn new(var: i32, next: Option<Box<Node>>) -> Node {
        Node { val, next }
    }
}

fn main() {
    let mut n = Box::new(Node::new(0, None));

    for i in 1..100000 {
        n = Box::new(Node::new(i, Some(n)));
    }
}

This is interesting. All the types here are fixed size, chaining boxes shouldn't cause any growth of a node on the stack. Yet this code overflows the stack. If I pass None to Box in the loop it works without any issue.

Original

struct Node {
    val: i32,
    next: Option<Box<Node>>,
}

impl Node {
    fn new(var: i32, next: Option<Box<Node>>) -> Node {
        Node { val, next }
    }
}

fn main() {
    let mut n = Box::new(Node::new(0, None));

    for i in 1..100000 {
        n = Box::new(Node::new(i, Some(n)));
    }

    println!("Does the program survive this long?");
}

Because this message prints, we can conclude that the stack overflow takes place when calling drop.

Yes, this code has a stack overflow in Box::drop because a box recursively drops its contents before itself. The great book Learning Rust With Entirely Too Many Linked Lists has a detailed discussion of this problem and its solutions in Chapter 2.7: Drop.

1 Like

Thanks!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.