Found this article with nice detailed explanation –
In C and C++, developers have direct access to memory. When a piece of
C or C++ code requests access to a block of memory, it is given the
specific address of the allocated memory, and the code directly reads
from and writes to that memory location. The advantage to this
approach is that direct access to memory is extremely fast and made
for efficient code. There are problems, however, that outweigh the
benefits. The problem with this direct memory access is that it is
easy to misuse, and misuse of memory causes code to crash. Misbehaving
C or C++ code can easily write to memory that has already been
deleted, or can write to memory belonging to another variable. These
types of memory access problems result in numerous hard-to-find bugs
and software crashes.The architecture of the CLR eliminates all of these problems by
handling memory management for you. This means that your C# code can
work with variables without needing to know details about how and
where the variables are stored in memory. Because the CLR shields your
C# code from these memory-related details, your C# code is free from
bugs related to direct access to memory.Occasionally, however, you need to work with a specific memory address
in your C# code. Your code may need that extra ounce of performance,
or your C# code may need to work with legacy code that requires that
you provide the address of a specific piece of memory. The C# language
supports a special mode, called unsafe mode, which enables you to work
directly with memory from within your C# code.This special C# construct is called unsafe mode because your code is
no longer safe from the memory-management protection offered by the
CLR. In unsafe mode, your C# code is allowed to access memory
directly, and it can suffer from the same class of memory-related bugs
found in C and C++ code if you’re not extremely careful with the way
you manage memory.
solved Why compiler force me to specify unsafe in c# [duplicate]