5

I am trying to check size of all of my variables (value types) using sizeof operator. I gone through one of the msdn article where it is written that

For all other types, including structs, the sizeof operator can be used only in unsafe code blocks

and also structs should not contain any fields or properties that are reference types

For this, I enabled unsafe compilation in my project properties and created structure as follows-

struct EmployeeStruct
{
    int empId;
    long salary;       
}

and used it as follows-

unsafe
{
   size = sizeof(EmployeeStruct);
}

Console.WriteLine("Size of type in bytes is: {0}", size);

Here I am getting output as Size of type in bytes is: 16 however by looking at structure it should be 12 (4 for int and 8 for long). Can someone help me understand here that why I am getting 4 byte extra size?

Prakash Tripathi
  • 469
  • 6
  • 12
  • The link you gave tells you: "whereas sizeof returns the size as it has been allocated by the common language runtime, **including any padding**" – DavidG Mar 12 '16 at 16:43
  • @EugenePodskal It changes a lot - people who are looking for answers to a problem on C# won't look at questions about C, they're very different languages, even if the answer is the same. – Gediminas Masaitis Mar 12 '16 at 16:48
  • @GediminasMasaitis Then they will find this question and read the duplicate (well, at least they should). But if you think that it is worth the effort, then you can write a proper canonical C#-specific answer. In that case I'd also recommend you to rename the question into more easily searchable and to-the-point "sizeof returns value that is greater than expected " or something along that line. – Eugene Podskal Mar 12 '16 at 16:53
  • Thnx for comment DavidG. Can you tell me more that why this padding is not interfering when obtaining size of any builtin types such as int, float etc. however it's giving extra size for structure. – Prakash Tripathi Mar 12 '16 at 16:53
  • 1
    Good suggestion Eugene Podskal. I have updated the title to have the specific comment. – Prakash Tripathi Mar 12 '16 at 16:57

1 Answers1

1

You don´t need to use unsafe code. Is recommended to use System.Runtime.InteropServices.Marshal.SizeOf()

eg: Marshal.SizeOf(new EmployeeStruct());

That return 16 instead of 12, because the default pack size in memory is 8.

So, for:

struct EmployeeStruct
{
    int empId; // 4 bytes
    long salary;  8 bytes
}

//return 16 instead 12 (because de min unit is 8)

for:

 struct EmployeeStruct
 {
    int empId; // 4 bytes
    int empAge; // 4 bytes
    long salary;  8 bytes
  }

//return 16 too

and for

   struct EmployeeStruct
   {
      int empId; // 4 bytes
      int empAge; // 4 bytes
      int IdCompany; // 4 bytes
      long salary;  8 bytes
   }

return 24 instead 20 (because de min unit is 8)

I don't know what you want, but if you need the sum of each field size, you can try with this function:

    public int SizeOf(Type t)
    {
        int s = 0;
        var fields = t.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
        foreach (var f in fields)
        {
            var x = f.FieldType;
            s += x.IsPrimitive ? Marshal.SizeOf(x) : SizeOf(x);
        }

        return s;
    }

It returns 12 instead 16, for your case, and you can use it for complex structures, eg:

    struct EmployeeStruct
    {
        int field1; // 4 bytes
        long field2; // 8 bytes
        Person p; // 12 bytes
    }

    struct Person
    {
        int field1; // 4 bytes
        long field2; // 8 bytes
    }  

SizeOf(typeof(EmployeeStruct) will return 24 instead 32, but remember, the REAL SIZE ON MEMORY is 32, the compiler use 32 bytes to assign memory.

Regards.

Gonzalo
  • 2,866
  • 7
  • 27
  • 42
  • But then why does a struct with three `int` has a size of 12 and not 16? – Kevin Gosse Mar 12 '16 at 17:15
  • Thnx Gonzalo. But isn't that true that System.Runtime.InteropServices.Marshal.SizeOf returns unmanaged allocated size after marshelling? Don't we have any way to get correct managed or CLR allocated size? – Prakash Tripathi Mar 12 '16 at 17:17
  • I edited my answer, maybe I can help you. Regards. – Gonzalo Mar 12 '16 at 18:16
  • @PrakashTripathi: Correct. The marshal size is -- not surprisingly -- the size of the buffer required to marshal the data. The sizeof size is the amount of memory the struct consumes. There is no reason why those two things have to be the same, and they often are not. – Eric Lippert Mar 13 '16 at 00:19
  • Thnx Eric Lippert. You sample to calculate size works like charm. However that opens a small question again that why in your sample, Marshal.SizeOf is not considering padding? – Prakash Tripathi Mar 13 '16 at 05:40