How to implement a struct contains str

I try to implement a virtual machine in rust. And I meet some problems when I implement the GC object. As an example, This is my String struct

struct GCHeader {
    // ignored
}
struct String {
    gcheader: GCHeader,
    str: str
}

The question is that the String object will be only allocated on heap and never be created on stack, so I tend to declare the second field as a type of str instead of String to avoid a second heap allocation. This struct then be unsized, trapped me when I implement the following functions.

impl String {
    fn new(s: &str) -> Box<Self> {
        // how to allocate memory and copy from the input string?
    }

    fn drop(self) {
        // how to free resource?
    }
}

So what is the correct way? The size of the struct need to be

sizeof(String) = 
    sizeof(GCHeader) 
      + sizeof(usize)  // length of string
      + sizeof(string_buffer) // the actual buffer for string

You can use SliceDst — Rust library // Lib.rs to do this, and use Erasable — Rust library // Lib.rs to make the pointer to it a thin pointer

Thanks for your nice advice. But I am curious why length in StrWithHeader is duplicatedly stored with the method len() in str. In addition, I need a struct of #[repr(packed)] insread of `#[repr(C)]' for the reason of memory usage. Anyway, it is a good reference for me.

I wouldn't use repr(packed) for this, since it disallowed getting references to any fields of your type (unless they have an alignment of 1).
The length method on the string reads from pointer. But if you se erasable, then the pointer won't store the length, so it must read from the data next to the string.

Default representation of &str

[Address, length]
|
\/
[Str data]

Representation of erasable::Thin<slice_dst::StrWithHeader<Header>>

[Address]
|
\/
[Len, header, str data]

As you can see, these crates just move where the length is stored.

Thanks for your impressive answer. I think it's the solution.

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.