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?
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));