diff --git a/ch4/fixing_ownership_issues/Cargo.lock b/ch4/fixing_ownership_issues/Cargo.lock
new file mode 100644
index 0000000..3377aa2
--- /dev/null
+++ b/ch4/fixing_ownership_issues/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "fixing_ownership_issues"
+version = "0.1.0"
diff --git a/ch4/fixing_ownership_issues/Cargo.toml b/ch4/fixing_ownership_issues/Cargo.toml
new file mode 100644
index 0000000..5be6719
--- /dev/null
+++ b/ch4/fixing_ownership_issues/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "fixing_ownership_issues"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/ch4/fixing_ownership_issues/src/main.rs b/ch4/fixing_ownership_issues/src/main.rs
new file mode 100644
index 0000000..6a910aa
--- /dev/null
+++ b/ch4/fixing_ownership_issues/src/main.rs
@@ -0,0 +1,113 @@
+// This section covers some common ownership errors.
+// I'll probably have to come back to this section. I'm not enjoying
+// this part of Rust so learning this is not my favorite.
+
+use std::rc::Rc;
+
+fn main() {
+    // ------------------------------------------------------------------------
+    // fixing an unsafe program: not enough permissions
+
+    let name = vec![String::from("Ferris!")];
+    let first = &name[0];
+    stringify_name_with_title(&name);
+    println!("{}", first);
+
+    // ------------------------------------------------------------------------
+    // fixing an unsafe program: copying vs. moving out of a collection
+
+    let v: Vec<i32> = vec![0, 1, 2];
+    let n_ref: &i32 = &v[0];
+    let n: i32 = *n_ref;
+
+    // If a value does not own head data, then it can be copied without a move
+    // Unlike what's happening below
+    // i32 doesn't own head data, so it can be copied without a move
+    // String does own heap data, so it can't be copied without a move
+    // &String doesn't own heap data, so it can be copied without a move
+    // Solution 1: Avoid taking ownership with immutable reference
+    let vs: Vec<String> = vec![String::from("Hello world")];
+    let s_ref: &String = &vs[0];
+    // let s: String = *s_ref;
+    println!("{s_ref}");
+    // Solution 2: Clone the data if want ownership
+    // Solution 3: Use Vec::remove to move string out of the vector
+
+    // ------------------------------------------------------------------------
+    // fixing an safe program: mutating different tuple fields
+
+    let mut name = (String::from("Ferris"), String::from("Rustacean"));
+    let first = &name.0;
+    name.1.push_str(", Esq.");
+    println!("{first} {}", name.1);
+}
+
+// fixing an unsafe program: returing a reference to the stack
+// fn return_a_string() -> &String {
+//     let s = String::from("Hello World");
+//     &s
+// fails because this function will get allocated but s is owned by this function.
+// }
+
+fn return_a_string_diff_owner() -> String {
+    let s = String::from("Hello world");
+    s
+}
+
+// static means it lives forever
+fn return_a_string_static() -> &'static str {
+    "Hello world"
+}
+
+// rc is a reference-counted pointer. More in ch14
+// only clones a pointer to s and not the data itself
+fn return_a_string_rc() -> Rc<String> {
+    let s = Rc::new(String::from("Hello world"));
+    Rc::clone(&s)
+}
+
+// caller provides a slot with a mutable reference
+fn return_a_string_slot(output: &mut String) {
+    output.replace_range(.., "Hello world");
+}
+
+// fixing an unsafe program: not enough permissions
+// Replace "&Vec<String>" with "$mut Vec<String>". THIS IS NOT A GOOD SOLUTION!
+// Functions shouldn't mutate their inputs if the caller would not expect it.
+// Basically just don't use mut in functions. Make a copy of the variable instead
+// if mutating it.
+fn stringify_name_with_title(name: &Vec<String>) -> String {
+    let mut name_clone = name.clone();
+    name_clone.push(String::from("Esq."));
+    let full = name_clone.join(" ");
+    full
+}
+
+fn stringify_name_with_title_final(name: &Vec<String>) -> String {
+    let mut full = name.join(" ");
+    full.push_str(" Esq.");
+    full
+}
+
+// fixing an unsafe program: aliasing and mutating a data structure
+// This function fails
+// fn add_big_strings(dst: &mut Vec<String>, src: &[String]) {
+//     let largest: &String = dst.iter().max_by_key(|s| s.len()).unwrap();
+//     for s in src {
+//         if s.len() > largest.len() {
+//             dst.push(s.clone());
+//         }
+//     }
+// }
+
+// The fix for above since we only need the length
+// Shortens the lifetime of borrows on dst to not overlap with
+//   mutation to dst.
+fn add_big_strings(dst: &mut Vec<String>, src: &[String]) {
+    let largest_len: usize = dst.iter().max_by_key(|s| s.len()).unwrap().len();
+    for s in src {
+        if s.len() > largest_len {
+            dst.push(s.clone());
+        }
+    }
+}