Summary
Wow, what a chapter. We learned a lot about memory management from a systems programming perspective, coupled with the knowledge of how the C++ and Rust languages treat memory. We learned about the stack and heap, and how the stack works automatically because of the scope rules that both C++ and Rust provide. We saw why the stack alone is not sufficient for writing programs: It is limited in size and has very narrow lifetime rules. We learned about ways to use the heap, which has much broader lifetime rules, but also saw that it is difficult to use the heap correctly. We then combined automatic stack cleanup with using the heap to create types that manage memory for us. We learned about ownership and why we have to care about it whenever we pass values around and create copies. We learned about the difference between copy-semantics and move-semantics. Lastly, we learned about references and borrows and saw that Rust takes special care to imbue borrows with the necessary information to prevent memory issues.
This is perhaps the most dense chapter in this whole book, so clap yourselves on the shoulder that you got through it. In the next chapter, we will apply this knowledge to write really good abstractions that C++ and Rust programmers use in their day-to-day life!