Зачем нужен unsafe код?
Подробно  внезапно описано в спецификации языка
https://docs.microsoft.com/ru-ru/dotnet/csharp/lan...

Если на пальцах то вы явно говорите компилятору что тут вы будете извращаться и заявляете что берете полную отвественность на себя.
Безопасный код осуществляет проверку типов. То есть, гарантируется что определенная область памяти содержит объект определенного типа. Небезопасный код позволяет обращаться к памяти без проверки типов.