Pop quiz: what does this line of code do when executed?
int foo = (*((int*)0));
If you’re an astute reader, you can solve the answer just by reading the title of the blog post. But, more interestingly, let’s forget about that buzzword and analyze exactly what’s happening. The access violation is probably the most common crash in unmanaged software, so let’s break it down piece by piece to discover what’s happening.
int * ip = NULL;
foo = *ip; //crash!
On the first line, we declare an integer variable named “foo”.
The second line declares a pointer to an integer named “ip”, and initializes this value to NULL (which is simply a fancy term for 0). Pointer variables “point” to a location in memory. In this case, we initialize it to point to the address NULL, or 0, of memory. Location “0” is in area of memory reserved by our operating system.
The third line attempts to grab the value of address 0, which is prohibited, and assign it to our variable “foo”. Our operating system smartly catches this and says “No way- you can’t see my reserved memory location!”. Our operating system shuts down this badly behaving application with an error like the following:
Unhandled exception at 0x004173c8 in cpractice.exe: 0xC0000005: Access violation reading location 0x00000000.
This error message is a bit cryptic, but it's understandable if broken down. 0xC0000005 is the error code designation for an Access Violation. 0x00000000 is the location that we tried to read (this is our NULL value!). And, 0x004173c8 is the arbitrary memory location where our application happened to be running at the time of the crash.
AV's can happen for both reading and writing, which is part of the reason that they are so common. Pointers in general are one of the most challenging topics in computer science, which is yet another reason this crash is so commonly seen.