WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Rust · Advanced · question 42 of 100

What is "unsafe" Rust, and when should you use it? Provide a practical example.?

📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

"Unsafe" Rust is a subset of the Rust language that provides developers with low-level control over the memory and execution behavior of their programs. This subset of Rust allows them to bypass the safety guarantees provided by the language’s built-in safety features and access low-level functionality like accessing raw memory, creating null pointers or dereferencing uninitialized pointers, etc.

Developers should use "unsafe" Rust when they need to manipulate memory or access hardware, particularly when working with low-level systems programming. The use of "unsafe" Rust can often yield significant performance improvements compared to safe Rust, particularly when dealing with large or complex data structures.

A practical example of "unsafe" Rust can be seen in implementations of certain data structures such as linked lists or hash tables. In safe Rust, these data structures are implemented using safe, high-level abstractions that abstract away the details of memory management and pointer manipulation to provide a simplified interface to the developer. However, in some scenarios, this abstraction can get in the way, and implementing these data structures using "unsafe" Rust can result in better performance.

For example, the Rust standard library’s ‘Vec‘ data structure uses safe Rust to manage its allocation and deallocation of memory. However, if you need to build a custom data structure like a linked list where you require more fine-grained control over the allocation and deallocation of memory, you may need to use "unsafe" Rust.

Here is an example of an ‘unsafe‘ linked list implementation:

    struct Node<T> {
        value: T,
        next: *mut Node<T>,
    }
    
    impl<T> Node<T> {
        fn new(value: T) -> *mut Node<T> {
            let node = Box::new(Node {
                value: value,
                next: std::ptr::null_mut(),
            });
            
            Box::into_raw(node)
        }
        
        unsafe fn append(&mut self, value: T) {
            let mut node = self;
            
            while !(*node).next.is_null() {
                node = &mut *(*node).next;
            }
            
            (*node).next = Node::new(value);
        }
    }

Here, we create a ‘Node‘ struct that represents a single node in the linked list. The ‘new‘ function creates a new node and returns a raw pointer to it. We use the ‘*mut‘ type here to represent the raw pointer.

The ‘append‘ function appends a new node to the end of the linked list. We use the ‘unsafe‘ keyword here because we are accessing raw pointers and dereferencing them, which is not allowed in safe Rust.

Overall, "unsafe" Rust can be a powerful tool, but it should be used with caution. It should only be used when the performance gains outweigh the risks of bypassing Rust’s safety guarantees. Developers should always thoroughly test their "unsafe" code and be aware of the potential security vulnerabilities that can arise from its use.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Rust interview — then scores it.
📞 Practice Rust — free 15 min
📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

All 100 Rust questions · All topics