Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sizeof operator gives extra size of a struct in C# [duplicate]

Tags:

c#

struct

sizeof

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?

like image 590
Prakash Tripathi Avatar asked Nov 08 '22 18:11

Prakash Tripathi


1 Answers

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.

like image 87
Gonzalo Avatar answered Nov 14 '22 21:11

Gonzalo