An ad-hoc implementation of the approach @kpreid mentioned to your example code looks like this
let mut empty_v: Vec<&str> = Vec::new();
loop {
let mut v = empty_v;
let data = String::from("Hello, world!");
// Fill the vector with some data bound to the scope of the loop.
v.push(data.as_str());
// sanity check: address stays the same
println!("{:p}", &v[..]);
// Do things with the data.
for s in &v { /* ... */ }
// Clear the vector, ensuring there is no references left in the vector.
v.clear();
empty_v = v.into_iter().map(|_| unreachable!()).collect();
}
(adapted from @kpreid's solution above as well as the code in a previous post of mine here)
Note that (as explained in the other post and subsequent discussion) you can skip the into_iter+collect step on the take side due to variance.