You write unsafe code by using two keywords: unsafe and fixed. The unsafe keyword specifies that the marked block will run in an unmanaged context. This keyword can be applied to all methods, including constructors and properties, and even to blocks of code within methods. The fixed keyword is responsible for the pinning of managed objects.
Pinning is the act of specifying to the garbage collector (GC) that the object in question cannot be moved. As it happens, during the execution of an application, objects are allocated and deallocated and "spaces" in memory open up. Instead of memory becoming fragmented, the .NET runtime moves the objects around to make the most efficient use of memory.
Obviously, this is not a good thing when you have a pointer to a specific memory address and then-unbeknownst to you-the .NET runtime moves the object from that address, leaving you with an invalid pointer. Because the reason the GC moves an object in memory is to increase application efficiency, you should use this keyword judiciously.