In this lesson, you will learn how to precisely control where data sits inside your structs to optimize memory usage and performance.
The Problem: Padding
When the .NET runtime creates a struct, it doesn't just jam the data together as tightly as possible. For performance reasons, the processor prefers to read data from memory addresses that are "aligned" to the size of the data type (e.g., a 4-byte integer likes to sit on an address divisible by 4).
If you have a byte followed by an int, the runtime will often insert invisible "padding" bytes between them so the int starts at a clean address. This makes your struct larger in memory than the sum of its individual fields.
The Solution: StructLayout
You can override this default behavior using the [StructLayout] attribute found in the System.Runtime.InteropServices namespace. By default, C# uses LayoutKind.Sequential, but you can exert more control:
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct CompactStruct
{
public byte MyByte; // 1 byte
public int MyInt; // 4 bytes
}
By setting Pack = 1, you tell the runtime to pack the fields together with 1-byte alignment. In this scenario, the total size of CompactStruct becomes 5 bytes instead of the default 8 bytes (where 3 bytes of padding would have been added).
Why control alignment?
- Memory Efficiency: If you are creating millions of instances of a struct, reducing padding can significantly lower your application's memory footprint.
- Interoperability: When you pass data to unmanaged code (like a C++ library or a hardware driver), the struct must match the exact binary layout expected by that system. If the C++ code expects a tightly packed structure, your C# struct must mirror that or the data will be misaligned and corrupted.
While it is tempting to pack everything tightly to save space, remember that misaligned data access can actually slow down CPU performance. Use these layout controls deliberately, specifically for high-volume objects or system-level integration.
Key Takeaway: The StructLayout attribute allows you to override default padding behaviors, enabling tighter memory packing or compatibility with low-level systems.