Some years ago I shared a trick that let’s you call _CrtCheckMemory from the debugger anywhere, without re-compilation. The updated (as of VS2013) string to type at a watch window is:
{,,msvcr120d.dll}_CrtCheckMemory()
Let’s expand on that today, in two steps.
Checking memory on every allocation
The CRT heap accepts a neat little flag, called: _CRTDBG_CHECK_ALWAYS_DF. Here’s how it used:
int main() { // Get current flag int tmpFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); // Turn on corruption-checking bit tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF; // Set flag to the new value _CrtSetDbgFlag(tmpFlag); int* p = new int[100]; // allocate, p[101] = 1; // corrupt, and… int* q = new int[100]; // BOOM! alarm fires here }
Testing for corruption on every allocation can tangibly slow down your program, which is why the CRT allows testing only every N allocations, N being 16, 128 or 1024. Usage adds half a line of code – pasted from MSDN:
// Get the current bits tmp = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); // Clear the upper 16 bits and OR in the desired frequency tmp = (tmp & 0x0000FFFF) | _CRTDBG_CHECK_EVERY_16_DF; // Set the new bits _CrtSetDbgFlag(tmp); }
Note that testing for corruption on every memory allocation is nothing like testing on every memory write – the alarm would not fire at the exact time of the felony, but since your software allocates memory (even indirectly) very often – this will hopefully help narrow down the crime scene quickly.
Checking memory on every allocation – from the debugger
You might reasonably want to enable/disable these lavish tests at runtime.
The debug flags are stored in {,,msvcr120d}_crtDbgFlag, and the numeric value of _CRTDBG_CHECK_ALWAYS_DF is 4, so one might hope that these lines would enable and disable these intensive memory tests:
Alas, this doesn’t work – _CrtSetDbgFlag contains further logic that routes the input flags further to internal variables. The easiest solution is to just call it:
First two lines enable, last two lines disable. If you’re running with non default flags, the actual values you’d see might be different.
Hi. Great post, but I’m a little unclear as the where to inject these calls. In the example it looks like the output of an object browser. What object is being browsed?
@Bob, if I understood you correctly – the screenshots are of a *watch* window
I typed {,,msvcr120d.dll}_CrtCheckMemory() into the watch1 window while running in debug mode and got this {,,msvcr120d.dll}_CrtCheckMemory() expression preceding parentheses of apparent call must have (pointer-to-) function type. Is there a trick I missed somewhere. I am using VS2013.