title: Why does using FieldOffset(0) in C# end up with different pointers for char array and string?
body: <p>As a follow up on the good answer for string immutability (<a href="https://stackoverflow.com/a/37253663/6619353">https://stackoverflow.com/a/37253663/6619353</a>) I've started experimenting with this technique to understand the offset of the modifiable bytes.</p>
  
  <p>Finally I've discovered that using <code>[FieldOffset(0)]</code> for two references fields does not make pointers have the same values.</p>
  
  <p>Here is the test:</p>
  
  <pre class="lang-cs prettyprint-override"><code>using System;
  using System.Runtime.InteropServices;
  
  namespace ConsoleApp
  {
      [StructLayout(LayoutKind.Explicit)]
      public struct MutableString
      {
          [FieldOffset(0)] 
          public readonly string AsString;
  
          [FieldOffset(0)] 
          public readonly char[] AsCharArray;
  
          public MutableString(string original)
          {
              AsCharArray = null;
              AsString = original;
          }
      }
  
      public static class Program
      {
          public static unsafe void Main(string[] args)
          {
              var mutableString = new MutableString("test");
  
              fixed (char* pString = mutableString.AsString, pCharArray = mutableString.AsCharArray)
              {
                  Console.WriteLine((long)pString);    // 2229380919860
                  Console.WriteLine((long)pCharArray); // 2229380919864
              }
          }
      }
  }
  </code></pre>
  
  <p>The code above prints different numbers (exact values will differ from time to time of course).</p>
  
  <p>The difference is always 4 bytes (2 chars).</p>
  
  <p>Here is the csproj file:</p>
  
  <pre><code>&lt;Project Sdk="Microsoft.NET.Sdk"&gt;
      &lt;PropertyGroup&gt;
          &lt;OutputType&gt;Exe&lt;/OutputType&gt;
          &lt;TargetFrameworks&gt;netcoreapp2.0;net47&lt;/TargetFrameworks&gt;
          &lt;AllowUnsafeBlocks&gt;true&lt;/AllowUnsafeBlocks&gt;
      &lt;/PropertyGroup&gt;
  &lt;/Project&gt;
  </code></pre>
  
  <p>Behavior is the same for .NET Core dll and net47 exe, Debug/Release, x86/x64 build configuration.</p>
  
  <p>Host machine is Win10 x64.</p>
  
  <p>I'm wondering how it is possible that after assigning only <code>AsString</code> field I'm getting <strong>another</strong> value in the field with the same offset?</p>