How to prevent dynamic memory allocation?

Many standards for safety-critical embedded code (which seems to be one of Rust's target markets) prevent the use of dynamic memory allocation outside of initialization.

See https://stackoverflow.com/questions/21370410/why-shouldnt-we-have-dynamic-allocated-memory-with-different-size-in-embedded-s/21370435 and http://mil-embedded.com/articles/justifiably-apis-militaryaerospace-embedded-code/ for reasoning.

The main points against dynamic memory allocation appear to be:

  • Creates the potential for memory leaks
  • Difficult to verify maximum potential memory usage
  • Heap access is non-deterministic, making it problematic for hard real-time systems

Rust appears to avoid the first issue with borrow-checking. However, the last two issues appear to still be valid.

I'm still new to Rust so apologies if I'm missing it (my literal first day learning it), but Rust doesn't appear to offer a relatively simple construct for mutable fixed-size strings like in C/C++? For instance, how could I do something like this in Rust?

const size_t FIXED_STR_SIZE_BYTES = 1024;

char testStr[FIXED_STR_SIZE_BYTES];
char str[10] = "hello";
strncpy(testStr, str, FIXED_STR_SIZE_BYTES);

Thanks!

I think that specific example would go something like this:


fn main() {
    const FIXED_STR_SIZE_BYTES: usize = 1024;
    
    // Create a u8 array, zero initialized, with size `FIXED_STR_SIZE_BYTES`
    let mut test_string = [0u8; FIXED_STR_SIZE_BYTES];
    // A utf-8 encoded string as a u8 array.
    let s = "hello".as_bytes();
    
    // Get a substring of `test_string` from the beginning up to the length of `s`
    // then copy the contents of `s` into it
    test_string[..s.len()].copy_from_slice(s);
}

If you're looking for something more ergonomic there's ArrayVec which includes ArrayVec and ArrayString types. However it's currently limited to small arrays because of a current (and hopefully temporary) limitation with Rust's type system.

4 Likes

Thanks!