Memory layout (layout) and size of struct instance fields in. NET managed environments (size)

Source: Internet
Author: User

Once a member of a struct type is declared, the layout order of the members in memory in the instance is determined by the same order as the member declaration, and is always aligned by default to the member with the largest space in the structure (Align). And, of course, we can set or encode the way memory is aligned.

In. NET managed environments, however, the CLR provides a freer way to control layout in a struct: we can use the StructLayoutAttribute attribute on a struct to control the memory layout of a member when defining a struct. By default, the layout order of the fields on the stack in a struct instance is the same as the order in the Declaration, that is, the [StructLayoutAttribute (layoutkind.sequential)] attribute is applied on the struct, The reason for this is that structs are often used in situations where interaction with unmanaged code occurs. If we are creating a struct type that does not have any interoperability with unmanaged code, we are likely to want to change this default rule for the C # compiler, so LayoutKind has two members auto and explicit in addition to the sequential members. Passing the Layoutkind.auto to StructLayoutAttribute allows the CLR to arrange the fields in the instance in the best way that it chooses, and the incoming layoutkind.explicit allows the field to be more flexible in accordance with the FieldOffset we set on the field The way the field is sorted, but this approach is also quite dangerous, if the consequences of setting errors will be more serious. Let's look at a few examples below, and figure out how many bytes are in each of the four structs.

1.[structlayout (layoutkind.sequential)]

structStructdeft//the C # compiler will automatically apply [StructLayout (layoutkind.sequential)]
...{
bool i; // 1Byte
double C; // 8byte
bool b; // 1byte
}

sizeof (STRUCTDEFT) obtained the result is 24byte! Aha, only 10byte of data in itself occupies 24byte of memory, because in the default (layoutkind.sequential) case, the CLR handles the layout of the struct in the same way as the default in C + +. That is, the members that occupy the largest space in the structure are aligned (Align). 10byte of data occupies 24byte, which is a serious waste of memory, so if we are creating a struct type that does not interoperate with unmanaged code, it is best not to use the default StructLayoutAttribute ( layoutkind.sequential) feature.


2.[structlayout (LAYOUTKIND.EXPLICIT)]

[StructLayout (LAYOUTKIND.EXPLICIT)]
structbadstruct
...{
[FieldOffset (0)]
Public BOOLi;//1Byte
[FieldOffset (0)]
Public DoubleC;//8byte
[FieldOffset (0)]
Public BOOLb;//1byte
}

sizeof (BADSTRUCT) obtained the result is 9byte, obviously the base 9 shows that the CLR does not have any memory alignment of the structure (Align), the data itself to occupy 10byte only 9byte, obviously some data is lost, This is why I give the struct a name badstruct. If [StructLayout (LAYOUTKIND.EXPLICIT)] is used on a struct, the calculation FieldOffset must be careful, for example, we use the above badstruct to perform the following tests:

structexpt e= Newstructexpt ();
E.C= 0;
E.I= true;
Console.WriteLine (e.c);

The result of the output is no longer 0, but 4.94065645841247E-324, because E.c and E.I share the same byte, and the execution "E.I = true;" Also changes the E.C,CPU to get this result when parsing e.c in the format of floating-point numbers. (For a floating-point number discussion, refer to my previous write, "Determine whether a floating-point number equals 0"). So in the use of layoutkind.explicit, please do not fieldoffset wrong:)

3.[structlayout (Layoutkind.auto)]

sizeof (Structauto) obtained the result is 12byte. Here's a test of how the three fields of this structauto are placed:

unsafe
...{
Structauto s= NewStructauto ();
Console.WriteLine (string. Format ("i:{0}", (int)&(S.I)));
Console.WriteLine (string. Format ("c:{0}", (int)&(S.C)));
Console.WriteLine (string. Format ("b:{0}", (int)&(s.b)));
}
//Test Results:
I:1242180
C:1242172
B:1242181

That is, the CLR adjusts the order of the fields in the struct, after I has been transferred to C, so that the Structauto instance s occupies as little memory as possible and 4byte memory alignment (Align), the field order adjustment results are as follows:


4. Size of an empty struct instance

structemptystruct...{}

Whether using the above LayoutKind explicit, auto or sequential, the resulting sizeof (EMPTYSTCT) are 1byte.


Conclusion:

By default (layoutkind.sequential), the CLR handles the layout of a struct in the same way as the default in C/E + +, which is aligned (Align) according to the members of the structure that occupy the most space.

With layoutkind.explicit , the CLR does not make any memory alignment (Align) to the struct, and we have to be careful that it is fieldoffset;

With Layoutkind.auto , the CLR adjusts the order of the fields in the struct so that the instance occupies as little memory as possible and makes 4byte of memory alignment (Align).

Memory layout (layout) and size of struct instance fields in. NET managed environments (size)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.