编译器如何检测内存损坏?C++动态数组越界异常解析
Great question—this is one of those behind-the-scenes details that shows how robust glibc's default heap allocator (ptmalloc2) is. Let’s walk through exactly what’s happening here.
First, let’s set the context: when you use malloc() or new (which calls malloc() under the hood in most implementations), the memory you get isn’t just the exact bytes you requested. glibc’s allocator adds extra "bookkeeping" data around your allocated block to manage the heap. This includes:
- The size of the allocated chunk
- Flags indicating if the block is in use or part of a larger free chunk
- Guard values (canaries) to catch accidental overwrites
- For large allocations, guard pages that trigger immediate faults if accessed
Now, let’s break down the two main ways glibc caught your out-of-bounds write:
1. Canary Value Checks (Most Common for Small/Medium Allocations)
When you allocate a chunk of memory, glibc inserts a random, secret "canary" value right after the user-accessible data. This value is generated once per process (or per allocation, depending on settings) and stored in a hard-to-predict location.
Here’s what played out in your case:
- You forgot to initialize the counter, so it held a garbage value that made you write past the end of your dynamic array.
- This write overwrote the canary value glibc placed after your array.
- Later, when you called
free(),realloc(), or even anothermalloc(), glibc checks the canary against its original stored value. If they don’t match, it knows something wrote to memory it shouldn’t have, and throws themalloc(): memory corruptionerror to prevent further damage.
The canary is specifically designed to catch this kind of off-by-one or out-of-bounds write that messes with the heap’s internal structure.
2. Guard Pages (For Larger Allocations)
For bigger memory blocks (usually larger than your system’s page size, like 4KB), glibc allocates "guard pages"—pages of memory marked as inaccessible via the mprotect() system call, set to PROT_NONE. These pages sit right before or after your allocated chunk.
If you write to these guard pages, your program will immediately trigger a segmentation fault (SIGSEGV). Sometimes glibc intercepts this and translates it into a malloc(): memory corruption error, but often it’s an immediate crash. This is a heavier-handed but effective way to catch large-scale out-of-bounds accesses.
Why the Error Didn’t Happen Immediately
You might have noticed the error popped up later, not right when you wrote to the illegal memory. That’s because glibc doesn’t check every single write (it would be far too slow). Instead, it runs these integrity checks during heap operations (like freeing or allocating memory) when it’s already interacting with the bookkeeping data.
In your scenario, the corrupted bookkeeping data lay dormant until the next time the allocator needed to use that part of the heap. At that point, it detected the tampering and crashed the program to avoid worse issues—like data corruption in other parts of your program or potential security vulnerabilities.
内容的提问来源于stack exchange,提问作者Ashutosh

