5
votes

I have a struct

struct Foo<'a> {
    buf: [u8, ..64],
    slice: &'a [u8]
}

The slice is supposed to point into the buf field of the struct. Is there any way to construct such a struct? Something like:

impl<'a> Foo<'a> {
    fn new() -> Foo<'a> {
        Foo {
            buf: [0, ..64],
            slice: ???? /* I don't know what to write here */
    }
}

If I try to do something like the following, the borrow checker complains (correctly), since the slice will have a shorter lifetime than the struct.

impl<'a> Foo<'a> {
    fn new() -> Foo<'a> {
        let buf = [0, ..64];
        Foo {
            buf: buf,
            slice: buf.slice_from(0)
        }
    }
}

I realize that for this simple case I could keep offsets and manually call the slice functions:

struct Foo {
    buf: [u8, ..64],
    slice_from: uint,
    slice_to: uint
}

However this question is just a simplification of a more general use case of a struct owning data and having references into the same data and I'm wondering if that is possible (in a safe way) in Rust.

1
I have asked a similar question (stackoverflow.com/questions/27092273/…) and unfortunately it seems like there is no safe way to do this.fjh

1 Answers

7
votes

No, you can't do it safely, because in general such a structure is not movable. Pretend it is possible, and you can create such a structure:

let foo = Foo {
    buf: [0, ..64],
    slice: obtain_slice_somehow()
};

The slice field is now a slice of buf field, in particular, it contains a pointer to buf, which is currently located on the stack. Now put foo into a box and return it from the function:

return Box::new(foo);

foo value is now moved to heap, and the function exits, freeing its stack memory. However, slice pointer is not adjusted to point to heap, because it is impossible to do in general, and so it left dangling, violating memory safety.