Contact Form

Name

Email *

Message *

Cari Blog Ini

Borrowed Data Escapes Outside Of Function

Escaping Borrowed Data in Rust Functions

Introduction

When working with borrowed data in Rust, it is important to ensure that the data is not used after the reference to it has been dropped. This can lead to undefined behavior and memory safety issues.

Case 1: Destructured Closure

Consider the following code: ``` fn main() { let s = "Hello"; let closure = || { println!("{}", s); }; drop(s); closure(); } ``` In this code, the string `s` is borrowed by the closure. However, after the closure is created, the string `s` is dropped. This means that the closure is now holding a reference to a dangling pointer, which will lead to a runtime error when the closure is executed. To fix this, we can either store a copy of the string in the closure or use a reference counted string.

Case 2: Spawning Threads

Another common case where borrowed data can escape is when spawning threads. Consider the following code: ``` fn main() { let s = "Hello"; let mut threads = vec![]; for i in 0..10 { let s_copy = s.clone(); let thread = std::thread::spawn(move || { println!("{}", s_copy); }); threads.push(thread); } drop(s); for thread in threads { thread.join().unwrap(); } } ``` In this code, the string `s` is cloned for each thread that is spawned. This is necessary because the string is borrowed by the closure that is passed to the thread. However, after the threads are spawned, the string `s` is dropped. This means that the closures that are running in the threads are now holding references to dangling pointers, which will lead to runtime errors when the closures are executed. To fix this, we can store a copy of the string in each thread.

Conclusion

It is important to be aware of how borrowed data can escape in Rust functions. By following the guidelines outlined in this article, you can help ensure that your code is memory safe and avoids undefined behavior.


Comments