title: Serializing & Deserializing a Struct Array
body: <p>In the following bit of code, I am observing that the marshaler is reading past the 3 byte source array to populate another 8 bytes of data.  With time, the code eventually throws a memory access violation.  Is there a way to tell the marshaller to only marshal the first 3 bytes when converting a pointer to a structure?  If I make the Articulations array "NonSerialized" then the constructor will throw an access violation when processing a source array of 11 bytes.</p>
  
  <pre><code>using System;
  using System.Runtime.InteropServices;
  
  namespace MarshallingTest
  {
      [StructLayout(LayoutKind.Sequential, Pack = 1)]
      public struct Articulation
      {
          public const int BaseSize = 8;
          public byte attribute1;
          public byte attribute2;
          public byte attribute3;
          public byte attribute4;
          public byte attribute5;
          public byte attribute6;
          public byte attribute7;
          public byte attribute8;
      }
  
      [StructLayout(LayoutKind.Sequential, Pack = 1)]
      public class TestEntity
      {
          public const int BaseSize = 3;
  
          public byte EntityId;         //  1 byte
          public byte Variable;         //  1 byte
          public byte NumArticulations; //  1 byte
  
          [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct)]
          public Articulation[] Articulations;   // 8 bytes each
  
          public TestEntity(byte[] rawData)
          {
              unsafe
              {
                  fixed (byte* pData = rawData)
                  {
                      // I am observing that the marshaler is reading past the 3 bytes
                      // to populate another 8 bytes of data.  With time, the code
                      // will eventually throw a memory access violation.
                      //
                      // Is there a way to tell the marshaller to only marshal the 
                      // first 3 bytes when converting a pointer to a structure?
                      Marshal.PtrToStructure((IntPtr) pData, this);
  
                      for (int i = 0; i &lt; BaseSize + Articulation.BaseSize; i++)
                      {
                          Console.WriteLine("pData + " + i + " = " + *(pData + i));
                      }
                  }
              }
          }
  
          public byte[] ToRaw()
          {
              byte[] byteArray = new byte[BaseSize + Articulation.BaseSize*Articulations.Length];
              unsafe
              {
                  fixed (byte* pData = byteArray)
                  {
                      Marshal.StructureToPtr(this, (IntPtr) pData, false);
                  }
              }
              return byteArray;
          }
      }
  
      internal class Program
      {
          private const int TestDataSize = TestEntity.BaseSize;
  
          private static void Main()
          {
              byte[] testData = new byte[TestDataSize];
              for (int i = 0; i &lt; TestDataSize; i++)
              {
                  testData[i] = (byte) (i + 1);
              }
              TestEntity test = new TestEntity(testData);
  
              // Print resulting array.  You'll see that data outside the source
              // byte array was marshalled into the test structure.
              Console.WriteLine(test.EntityId);
              Console.WriteLine(test.Variable);
              Console.WriteLine(test.NumArticulations);
              Console.WriteLine(test.Articulations[0].attribute1);
              Console.WriteLine(test.Articulations[0].attribute2);
              Console.WriteLine(test.Articulations[0].attribute3);
              Console.WriteLine(test.Articulations[0].attribute4);
              Console.WriteLine(test.Articulations[0].attribute5);
              Console.WriteLine(test.Articulations[0].attribute6);
              Console.WriteLine(test.Articulations[0].attribute7);
              Console.WriteLine(test.Articulations[0].attribute8);
  
              Console.WriteLine("Test complete.");
          }
      }
  }
  </code></pre>