What is memory safety, and why does it matter so much?
A property of a language or system guaranteeing that a program cannot access memory it should not — no reading past the end of a buffer, no using freed memory, no dereferencing invalid pointers. Its absence is responsible for a very large share of serious security vulnerabilities.
The specific failure classes:
Buffer overflow, writing past an allocation's end into adjacent memory — historically the foundation of exploitation, since it can overwrite return addresses and redirect execution.
Use-after-free, accessing memory that has been released and may now hold something else. Now among the most exploited classes, because it is subtle and hard to detect by reading.
Double free, corrupting allocator structures.
Out-of-bounds read, leaking adjacent memory — the mechanism behind several high-profile data disclosures.
Null pointer dereference, generally a crash rather than a compromise.
Uninitialised memory, producing non-deterministic behaviour and leaking previous contents.
Why it matters at scale. Analyses by several large vendors have independently found that roughly two-thirds to seventy percent of their serious vulnerabilities were memory safety issues. That consistency across different codebases and companies is what made this a policy question rather than a stylistic one, and national security agencies have publicly recommended moving to memory-safe languages.
How languages achieve safety:
Garbage collection, where the runtime manages lifetimes — safe, at the cost of runtime overhead and pauses.
Ownership and borrowing, checked at compile time, giving safety without a garbage collector — which is what made it viable for systems programming that previously had no safe option.
Bounds checking, verifying indices at runtime.
References without pointer arithmetic.
Why unsafe languages persist: enormous existing codebases, performance ceilings in specific domains, hardware and embedded constraints, and the cost of rewriting working software.
What is done instead: hardening — address space randomisation, stack canaries, control-flow integrity, hardware memory tagging — plus sanitisers, fuzzing and static analysis. These raise the cost of exploitation without removing the class, which is the essential difference.