When we work with pointer-based languages, we can possibly encounter dangling references. Not so in Rust. Dangling References in Rust are automatically taken care of by the compiler at compile-time.

In this post, we will understand what dangling references are and how Rust avoids them.

If you are new to the concept of references in Rust, I will recommend going through this detailed post on Rust Borrowing Mutable References.

1 – What is a Dangling Reference?

Dangling references are usually a result of erroneous coding.

Basically, a dangling reference is a pointer that references a location in memory that may have been given to someone else. The memory may have been freed. However, a pointer to that memory persists in the program.

See below illustration that describes the dangling reference pointer.

rust dangling references
Dangling Reference Example

Even when the msg and the memory assigned to the data are removed, the reference (&msg) remains. Since it exists on its own, it is known as a dangling reference.

2 – How Rust Handles Dangling References?

In Rust, the compiler guarantees that references will never be dangling references.

In other words, if you have a reference to some data, the compiler will ensure that the data will not go out of scope before the reference to the data goes out of scope.

Check out the below example where we try to create a dangling pointer in Rust.

fn main() {
    let reference_to_nothing = create_dangling_reference();
}

fn create_dangling_reference() -> &String {
    let greeting_msg = String::from("Greetings from the future");

    &greeting_msg
}

The function create_dangling_reference() attempts to create a dangling pointer. It returns the reference to greeting_msg. You can read more on functions in this detailed post.

However, greeting_msg goes out of the scope at the end of the function. Once it is out of scope, the underlying memory will also go away. In other words, greeting_msg will be de-allocated.

Basically, we will end up with an invalid reference or a dangling reference to the String. This is not acceptable to the Rust compiler.

Therefore, on trying to compile the above program, we get the below error message.

error[E0106]: missing lifetime specifier
 --> src/main.rs:5:35
  |
5 | fn create_dangling_reference() -> &String {
  |                                   ^ expected named lifetime parameter
  |
  = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from

The error message does talk about the concept of lifetime. More on that in a later post. However, the bottom line is that Rust prevents the creation of a dangling reference.

To get around this, we should instead return the string. See below:

fn main() {
    let msg = create_dangling_reference();
}

fn create_dangling_reference() -> String {
    let greeting_msg = String::from("Greetings from the future");

    greeting_msg
}

In this case, ownership is properly transferred and nothing is deallocated.

Conclusion

As developers, we don’t need to worry about dangling references or pointers in Rust. The compiler takes care of avoiding dangling references.

However, knowing about them helps us understand the right approach to design our functions in Rust.

Want to learn more about Rust? Check out this post on Rust Ownership.

If you have any comments or queries about this post, please feel free to mention them in the comments section below.

Categories: BlogRust

Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *