Title. I’m looking for a concrete answer for this.

  • z3rOR0ne
    link
    fedilink
    arrow-up
    1
    ·
    1 month ago

    I’m new to C and Rust, but from what I can gather, C and C++ are not memory safe by default because they require the programmer to manually allocate memory onto the heap as needed and then free said memory, and then remember not to use said freed memory again. There is a lot of “ceremony” around this and it’s easy to make mistakes, which result in memory leaks, use after free errors, undefined behavior, security bugs, etc.

    Most high level languages (Python, JavaScript, Java, Golang, etc.) use a garbage collector (also known by the acronym, GC), which very essentially looks for when memory can be freed within your program and performs this allocation/deallocation ceremony for you. There are, however, disadvantages to running a garbage collector. Running a garbage collector costs allocation of memory itself, and it is not inherently efficient (depending on how the garbage collector itself was implemented).

    Rust’s solution to this utilizes techniques built around the concept of memory ownership, which is enforced using what is known as the Borrow Checker. In essence, Rust prevents memory leaks by ensuring that a variable (i.e. a reference to a value stored in memory) cannot be utilized in multiple different scopes of the program, but rather must be either copied (a new variable with the same value stored in a different space of memory), or the variable must be passed directly to the new scope, afterwards which it cannot be utilized outside of the scope it was passed to (hence the term of it being “borrowed”.)

    Im not sure, but I believe this is why Rust is more efficient than a garbage collected language because the techniques used in garbage collection can be computationally and resource intensive. These techniques include tracing, reference counting, and escape analysis.

    This is as opposed to Rust’s memory management model, which prevents memory leaks by explicit memory allocation of mutable variables which prevents the presence of dangling pointers being left within the codebase.

    From my little experience working with both C and Rust, as well as languages like JS/TS and Python, is that Rust cuts the difference between the low level languages like C and the GC languages like Python in that you don’t have to manually allocate and deallocate memory every time you need to use the heap, but you need to keep track of which scope owns which memory at any given time, otherwise the compiler (and hopefully long before that, your linter) will complain at you and prevent you from even compiling a binary in the first place.

    Lastly, a point of interest. C++ has an optional borrow checker of sorts in its use of RAII.

    Hope this helps sort things out a bit. Really there aren’t many memory safe languages that use the ownership model. All GC languages are memory safe (assuming the GC is implemented well), but the computational cost of that memory safety is higher than with Rust.

    In short, Rust’s Ownership model makes Rust one of the few memory safe languages that is nearly as efficient as manually memory allocated languages like C, while still memory safe like with GC languages.