If one is fortunate enough to have access to <crtdbg.h> from Microsoft’s Visual C++ header, when running in debug mode there are a few _Crt*** functions that can be pretty useful. My favorite ones are _CrtCheckMemory and _CrtDbgBreak (which is just a macro for __debugbreak in my case).
This function checks padding bytes around allocations made by the debug heap for buffer overruns. Usually this is not too necessary if you just do bounds checking yourself in debug mode, though sometimes old code crops up that you didn’t even write yourself, and needs debugging.
Lucky enough for me I had a good guess as to where the corruption was coming from as I had some call stacks in-tact from my crash. Finding the heap corruption was easy in my particular case since the code is deterministic and can be re-run quickly. Sprinkling this macro around will let me back-trace through the code to find exactly where the first instance of corruption happened:
#include <crtdbg.h> #define CHECK_MEM( ) \ do \ { \ if ( !_CrtCheckMemory( ) ) \ { \ _CrtDbgBreak( ); \ } \ } while( 0 )
A few minutes later I ended up here:
CHECK_MEM( ); Mutate( population, chromSize, probMutate ); CHECK_MEM( ); // code breakpointed right here
Since my breakpoint activated just after this function call, but not before, I knew the corruption came from this pesky function. Turns out it was a weird typo that was really sneaky, just barely causing an off-by-one error.
See if you can spot the error below. Here’s the answer (text is white, so highlight it to read): on line 8 chromSize needs to be changed to i.
void Mutate( char* child, int chromSize, float probMutate ) { for ( int i = 0; i < chromSize; ++i ) { if ( Random01( ) < probMutate ) { // flip a random bit child[ chromSize ] ^= (char)1 << (rand( ) % 8); } } }