Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the use of C# keyword fixed/unsafe? [duplicate]

Tags:

c#

What's the use of C# keyword fixed/unsafe?

For example, C# fixed Keyword (unsafe)

using System;

class Program
{
    unsafe static void Main()
    {
        fixed (char* value = "sam")
        {
            char* ptr = value;
            while (*ptr != '\0')
            {
                Console.WriteLine(*ptr);
                ++ptr;
            }
        }
    }
}

Why do I need to fix it in the first place?

like image 922
Swab.Jat Avatar asked Feb 24 '14 07:02

Swab.Jat


3 Answers

C# is a managed language that means the memory is managed automatically, i.e. not by you. If you did not use fixed by the time you come to modify the memory pointed to by your pointer C# could have moved the variable to another memory location so you could be modifying something else!

fixed is logically fixing the variable in memory so it does not move around.

Why does C# move variables in memory around? To compact the memory otherwise programs would use up more memory available to them if objects that are no longer alive left holes other objects cannot fit in (heap memory fragmentation).

I used fixed extensively in a .NET library designed for resource constrained devices to avoid creating garbage copying into buffers and find this feature sorely lacking in other managed languages where you cannot do the same. When writing games in a managed language garbage collection is often one of the biggest bottlenecks so having the ability not to create it is very helpful!

See my question here: C# Copy variables into buffer without creating garbage? for one reason why.

like image 60
markmnl Avatar answered Oct 19 '22 14:10

markmnl


unsafe is necessary to deal in pointers.

fixed has two uses:

  • it allows you to pin an array and obtain a pointer to the data
  • when used in an unsafe struct field, it declares a "fixed buffer" - a reserved block of space in a type that is accessed via pointers rather than regular fields

To answer with a specific example - here's some code that is used to perform semantic equality between two byte[] of arbitrary size...

    internal static unsafe  int GetHashCode(byte[] value)
    {
        unchecked
        {
            if (value == null) return -1;
            int len = value.Length;
            if (len == 0) return 0;
            int octects = len / 8, spare = len % 8;
            int acc = 728271210;
            fixed (byte* ptr8 = value)
            {
                long* ptr64 = (long*)ptr8;
                for (int i = 0; i < octects; i++)
                {
                    long val = ptr64[i];
                    int valHash = (((int)val) ^ ((int)(val >> 32)));
                    acc = (((acc << 5) + acc) ^ valHash);
                }
                int offset = len - spare;
                while(spare-- != 0)
                {
                    acc = (((acc << 5) + acc) ^ ptr8[offset++]);
                }
            }
            return acc;
        }            
    }

So if, for example, the buffer was 1000 items, by treating it as a set of long we now only do 125 iterations rather than having to look individually at all 1000 - plus we completely bypass any array bounds checking (which the JIT may or may not remove, depending on how obvious it looks that you can't possibly be violating them).

like image 30
Marc Gravell Avatar answered Oct 19 '22 15:10

Marc Gravell


Unsafe code blocks are quite rare to be used. They are predominantly used if you want to create and make use of pointers. Also, any code in unsafe block is out of control of CLR. It is considered to be unverifiable (from MSDN) as far as CLR in concerned.

Now, when garbage collection happens, some object may well be relocated. When prefixed with fixed, we are telling the framework to not to relocate objects whose address pointers are pointing to.

like image 4
danish Avatar answered Oct 19 '22 16:10

danish