The guard page trick is neat, but it has limitations. If you are already using malloc/free (or can swap your allocations to use it instead), then using something like
Address Sanitizer will generally give you better results.
From that link:
The tool can detect the following types of bugs:
* Out-of-bounds accesses to heap, stack and globals
* Use-after-free
* Use-after-return (runtime flag ASAN_OPTIONS=detect_stack_use_after_return=1)
* Use-after-scope (clang flag -fsanitize-address-use-after-scope)
* Double-free, invalid free
* Memory leaks (experimental)
Typical slowdown introduced by AddressSanitizer is 2x.
It's built into Clang (and recent versions of GCC), you can just pass -fsanitize=address to the compiler and linker.