sizeof(char) vs SizeOf(char)

May 6, 2008 at 10:59 PMAndre Loker

This is weird.

   1: using System;
   2: using System.Runtime.InteropServices;
   3:  
   4: public class Program {
   5:     public static void Main() {
   6:         Console.Out.WriteLine("sizeof(char) = {0}", sizeof (char));
   7:         Console.Out.WriteLine("Marshal.SizeOf(typeof(char)) = {0}", Marshal.SizeOf(typeof(char)));
   8:     }
   9: }

 

Output:

   1: sizeof(char) = 2
   2: Marshal.SizeOf(typeof(char)) = 1

And here is why: Of course Marshal.SizeOf handles different character sets when strings fields in structures are marshalled. An interesting point is that when no character set is explicitly given, the CLR assumes CharSet.Ansi. As System.Char has no CharSet defined, SizeOf calculates the marshalled size assuming Ansi encoding. When the char is within a struct, the StructLayoutAttribute can be used and is honoured by SizeOf:

   1: using System;
   2: using System.Runtime.InteropServices;
   3:  
   4: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
   5: public struct Ex1 {
   6:     private char x;
   7: }
   8:  
   9: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
  10: public struct Ex2 {
  11:     private char x;
  12: }
  13:  
  14: public class Program {
  15:  
  16:     public static unsafe void Main() {
  17:         Console.Out.WriteLine("sizeof(Ex1) = {0}", sizeof (Ex1));
  18:         Console.Out.WriteLine("Marshal.SizeOf(typeof(Ex1)) = {0}", Marshal.SizeOf(typeof (Ex1)));
  19:         Console.Out.WriteLine("sizeof(Ex2) = {0}", sizeof (Ex2));
  20:         Console.Out.WriteLine("Marshal.SizeOf(typeof(Ex2)) = {0}", Marshal.SizeOf(typeof (Ex2)));
  21:     }
  22: }
   1: sizeof(Ex1) = 2
   2: Marshal.SizeOf(typeof(Ex1)) = 1
   3: sizeof(Ex2) = 2
   4: Marshal.SizeOf(typeof(Ex2)) = 2

This looks more realistic again. sizeof(Ex1) both return the same size the structs occupy in memory (which is 2 bytes because of the unicode character). Marshal.SizeOf(typeof(Ex1)) return the marshalled size, which is 1 because I chose Ansi as the character set. Similarly, the marshalled size of Ex2 is 2 because of the unicode character set.

Posted in: C#

Tags: ,