更改缓冲区的分配大小不会更改程序的输出

时间:2018-01-12 14:43:31

标签: c# buffer fixed

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");
            }
        }
    }
}

我正在阅读NutShell中的c#6.0,第189页,有一个固定大小缓冲区的示例程序。我改变了行

public fixed byte Buffer[30]

public fixed byte Buffer[1]

我希望有一些超出边界的例外,但程序仍然运行相同而没有错误。在示例中,“Christian Troy”的长度超过1。有人可以解释一下原因吗?

1 个答案:

答案 0 :(得分:1)

您的代码不会崩溃,因为您将p声明为指针(byte* p)。因此,p[i] = (byte) s[i];不是通过Array类访问缓冲区,而是直接操作内存。 你的指令变成类似于(伪代码)的东西

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

行为是不可预测的,取决于内存的布局方式。特别是,在您的情况下,您将在变量存储之后覆盖分配给流程的内存的一部分。由于你正在处理几个字节,所以你没有任何例外。

如果你写了一个非常长的字符串,比方说5000个字符,你会尝试粉碎那个更多的段,你会看到异常。

试试这个:

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