I would generally agree. However, one other case where memory could leak is if you fill data structures and never remove the contents (i.e. only grow the structure). An example could look like this:
use std::cell::RefCell;
thread_local! {
static BUF: RefCell<String> = RefCell::new(String::new());
}
fn quote(s: &str) -> String {
BUF.with(|buf| {
let mut buf = buf.borrow_mut();
let start = buf.len();
buf.push('"');
buf.push_str(s);
buf.push('"');
eprintln!("buffer len = {}", buf.len());
buf[start..].to_owned()
})
}
fn main() {
for _ in 0..10 {
assert_eq!(quote("Hello"), "\"Hello\"");
}
}
This example neither uses Rc
or Arc
nor mem::forget
or ManuallyDrop
, etc., but the foo
function does leak memory.
Whether the leak is explicit or not is arguable, I guess.
I understand this example is a bit awkward, but I'm sure there are other scenarios where you accidentally grow structures more and more, which effectively results in a leak, so I wanted to mention this as another sceneraio where memory leaks might happen.
The example I gave is different from leaks through Rc
/Arc
and mem::forget
insofar that the memory is, in theory, still reachable (at least from within the module). However, as I understand the term "memory leak" right, not all leaks require memory to be unreachable (Wikipedia).