3 ms·
This might clarify the situation, for C or C++ folks: // heap-allocated, fixed-size struct BoxStr { unsigned length; // INVARIANT: this
by School-Cotton 4y ago
This might clarify the situation, for C or C++ folks:
// heap-allocated, fixed-size
struct BoxStr {
unsigned length;
// INVARIANT: this points to a heap allocation of length bytes, and is valid utf8
unsigned char *data;
}
// heap-allocated, resizable
struct String {
unsigned length;
unsigned capacity;
// INVARIANT: heap allocation of capacity bytes, the first length of which are valid utf8
unsigned char *data;
}
Of course you could resize BoxStr, but only by reallocating `data` to the exact desired length every time, which will kill your asymptotic complexity.
- tylerhou 4y agoIs your first example really equivalent to Box<str>? I would have expected something like using BoxStr = std::unique_ptr<Str>; where Str is defined as struct Str { size_t len; char data[]; }; The difference is that the len is stored on the heap, and the data is stored inline with the length. Unfortunately C++ does not support flexible array members so this syntax is not actually valid. Edit: Never mind, after reading the article Rust does use the above representation because Box holds a “fat” pointer to str, which stores it’s length on the stack. So BoxStr is the correct equivalent, because &[u8] is not equivalent to u8*, it’s equivalent to std::span<u8>.
- steveklabnik 4y agoYour parent is correct, the length is stored alongside the pointer, not on the heap with its data. This is true for any "dynamically sized type," not just Box<str>. &str is also a (pointer, length) pair, for example.