A scope determines where a binding is usable and when its local value leaves use. A function creates a scope; braces can create a smaller block scope inside it. Scope also gives resource cleanup a predictable boundary: a local pointer may disappear when a function returns, but the resource it points to needs its own cleanup. section 4.1.1
A block can shadow a binding
In `int a = 0; { int a = 1; printf("%d", a); } printf("%d", a);`, the first print uses the inner `a` and produces `1`. After the block ends, the outer `a` is visible again, so the second produces `0`. section 4.1.1
In C, leaving a function releases its local pointer but does not free heap memory allocated with `malloc`. An early return can therefore skip both `free` and `fclose`. C++ RAII ties cleanup to objects such as `std::shared_ptr` and `std::ifstream`, so leaving scope also runs their cleanup. section 4.1.1
void leaky_func() {
FILE *fp;
int *a = malloc(sizeof(int));
*a = 0; #1
// try to open a file for reading
fp = fopen("file.txt", "r");
if (fp == NULL) {
// there was an error!
return;
}
// Now we can read from the file at fp.
// ...
fclose(fp); #2
free(a); #3
}
Follow the error return: it occurs after allocation but before `free(a)`, leaving the allocated memory unreleased. section 4.1.1
Rust also uses scope for RAII cleanup. When an owned value goes out of scope, its destructor runs; a container such as `Vec` cleans up its contents too. Ownership moves matter: after a `String` is moved into a `Vec`, the vector owns it. The notable exceptions here are `Copy` values, which cannot have destructors, and unsafe code. section 4.1.2
Listing 4.1 Resource acquisition
fn main() {
let status = String::from("Active"); #1
let statuses = vec![status]; #2
println!("{:?}", statuses);
} #3
Trace `status` into `statuses`: the move transfers ownership, and the vector and its contents are cleaned up when `main` ends. section 4.1.2




















