更改缓冲区的分配大小不会更改程序的输出
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");
}
}
}
}
我正在看书 c#6.0 in a NutShell,第 189 页,有一个固定大小缓冲区的示例程序。我更改了行
public fixed byte Buffer[30]
到
public fixed byte Buffer[1]
我希望有一些越界异常,但程序仍然 运行 没有错误。在示例中 "Christian Troy" 超过 1 个长度。有人可以解释一下为什么吗?
您的代码不会崩溃,因为您将 p
声明为指针 (byte* p
)。因此,p[i] = (byte) s[i];
不是通过 Array
class 访问缓冲区,而是直接操作内部内存。
你的指令变成了类似于(伪代码)
memory(addressof(p) + (i * sizeof(byte))) = (byte) s[i];
该行为是不可预测的,取决于内存的布局方式。特别是,在您的情况下,您将在变量存储之后覆盖分配给您的进程的一部分内存。由于您处理的字节数很少,因此不会出现任何异常。
如果你写了一个很长的字符串,比方说 5000 个字符,你将尝试粉碎该段,并且你会看到异常。
试试这个:
new UnsafeClass(new string ('a', 5000));
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");
}
}
}
}
我正在看书 c#6.0 in a NutShell,第 189 页,有一个固定大小缓冲区的示例程序。我更改了行
public fixed byte Buffer[30]
到
public fixed byte Buffer[1]
我希望有一些越界异常,但程序仍然 运行 没有错误。在示例中 "Christian Troy" 超过 1 个长度。有人可以解释一下为什么吗?
您的代码不会崩溃,因为您将 p
声明为指针 (byte* p
)。因此,p[i] = (byte) s[i];
不是通过 Array
class 访问缓冲区,而是直接操作内部内存。
你的指令变成了类似于(伪代码)
memory(addressof(p) + (i * sizeof(byte))) = (byte) s[i];
该行为是不可预测的,取决于内存的布局方式。特别是,在您的情况下,您将在变量存储之后覆盖分配给您的进程的一部分内存。由于您处理的字节数很少,因此不会出现任何异常。
如果你写了一个很长的字符串,比方说 5000 个字符,你将尝试粉碎该段,并且你会看到异常。
试试这个:
new UnsafeClass(new string ('a', 5000));