Search code examples
c#bufferfixed

Change the allocate size of buffer doesn't change output of the program


using System;

namespace Page189
{
    unsafe struct UnsafeUnicodeString
    {
        public short Length;
        public fixed byte Buffer[30]; // Allocate block of 30 bytes, I change the 30 to 1, expected to have some outofboundary exception, but nothing happens

    unsafe class UnsafeClass
    {
        UnsafeUnicodeString uus;

        public UnsafeClass(string s)
        {
            uus.Length = (short) s.Length;
            fixed (byte* p = uus.Buffer)


                for (int i = 0; i < s.Length; i++)
                {
                    p[i] = (byte) s[i];
                    Console.Write((char)p[i]);//this line is added by myself
                }
            }
        }

        class Test
        {
            static void Main()
            {
                new UnsafeClass("Christian Troy");
            }
        }
    }
}

I am reading book c#6.0 in a NutShell, on page 189, there is an example program of Fixed-Sized buffers. I changed the line

public fixed byte Buffer[30]

to

public fixed byte Buffer[1]

and I am expecting to have some out of boundary exceptions but program still running the same with no errors. In the example "Christian Troy" is more than 1 length. Could some one please explain why?


Solution

  • Your code does not crash because you declared p as a pointer (byte* p). For this reason, p[i] = (byte) s[i]; is not accessing the buffer through the Array class, but is directly manipulating the inner memory. Your instruction is turned into something similar to (pseudo code)

    memory(addressof(p) + (i * sizeof(byte))) = (byte) s[i];

    The behavior is unpredictable and depends on how the memory is laid out. Particularly, in your case, you are overwriting a portion of memory allocated to your process after your variable storage. As your are dealing with few bytes, your are not getting any exception.

    If you write a very long string, let's say 5000 characters, you will try to smash that segment currupting much more, and you'll see the exception.

    Try this:

    new UnsafeClass(new string ('a', 5000));