A memory corruption is one of the most intractable forms of programming error for
two reasons. First, the source of the corruption and the manifestation might be far
apart, making it difficult to correlate cause and effect. Second, symptoms appear
under unusual conditions, making it hard to consistently reproduce the error.
Fundamentally, memory corruption occurs when one or both of the following are
true.
■ The executing thread writes to a block of memory that it does not own.
■ The executing thread writes to a block of memory that it does own, but corrupts the state of that memory block.
To exemplify the first condition, consider this small application:
#include <windows.h>
#define BAD_ADDRESS 0xBAADF00D
int __cdecl wmain (int argc, wchar_t* pArgs[])
{
char* p =(char*)BAD_ADDRESS;
*p=’A’;
return 0;
}
This small application declares a pointer to a char data type and initializes the pointer to an address for which it does not have access (0xBAADF00D). The net result of running the application is a crash, and the dreaded Dr. Watson UI pops up. Although it’s very clear that this simple application performs an invalid memory access, more complex systems can be trickier to figure out.