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。有人可以解释一下原因吗?
答案 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));