Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I check the number of bytes consumed by a structure?

Tags:

c#

.net

byte

If I am creating a relatively large structure, how can I calculate the bytes it occupies in memory?

We can do it manually, but if the struct is large enough then how do we do it? Is there some code chunk or application?

like image 958
Simsons Avatar asked Jul 29 '10 11:07

Simsons


People also ask

How many bytes does a structure take?

Contrary to what some of the other answers have said, on most systems, in the absence of a pragma or compiler option, the size of the structure will be at least 6 bytes and, on most 32-bit systems, 8 bytes. For 64-bit systems, the size could easily be 16 bytes.

How many bytes of memory does a struct take?

struct { unsigned int widthValidated; unsigned int heightValidated; } status; This structure requires 8 bytes of memory space but in actual, we are going to store either 0 or 1 in each of the variables. The C programming language offers a better way to utilize the memory space in such situations.

How can you determine the number of bytes allocated to each data type in C?

It varies depend upon the processor in the CPU that we use. If we are using 16 bit processor, 2 byte (16 bit) of memory will be allocated for int data type. Like wise, 4 byte (32 bit) of memory for 32 bit processor and 8 byte (64 bit) of memory for 64 bit processor is allocated for int datatype.

What is the C operator that counts the number of bytes in a variable structure or array?

sizeof is a unary operator in the programming languages C and C++. It generates the storage size of an expression or a data type, measured in the number of char-sized units.


2 Answers

Structs have been troublesome beasts in computer engineering for a very long time. Their memory layout is very hardware dependent. To make them efficient, their members must be aligned so the CPU can read and write their values quickly without having to multiplex the bytes to fit the memory bus width. Every compiler has its own strategy of packing the members, often directed by, for example, the #pragma pack directive in a C or C++ program.

Which is okay, but rather a problem in interop scenarios. Where one chunk of code may make different assumptions about the structure layout than another chunk, compiled by a different compiler. You can see this back in COM, .NET's grandfather solution to interop programming. COM has very poor support for handling structs. It doesn't support them as a native automation type but has a workaround through the IRecordInfo interface. Which lets a program discover the memory layout at runtime through an explicit declaration of the structure in a type library. Which works okay, but is quite inefficient.

The .NET designers made a very courageous, and correct, decision to solve this problem. They made the memory layout of a struct completely undiscoverable. There is no documented way to retrieve the offset of a member. And by extension, no way to discover the size of the struct. Everybody's favorite answer, use Marshal.SizeOf() is not in fact the solution. That returns the size of struct after it is marshaled, the size you'd need to pass to, say, Marshal.AllocCoTaskMem() before you call Marshal.StructureToPtr. That arranges and aligns the struct members according to the [StructLayout] attribute that's associated with the struct. Note that this attribute isn't required for structs (like it is for classes), the runtime implements a default one which uses the declared order for the members.

One very nice side-effect of the layout being undiscoverable is that the CLR can play tricks with it. When packing the members of the struct and aligning them, the layout can get holes that don't store any data. Called padding bytes. Given that the layout is undiscoverable, the CLR can actually use the padding. It moves a member if it is small enough to fit such a hole. You'll now actually get a struct whose size is smaller than what would normally be required given the declared structure layout. And, notably, Marshal.SizeOf() will return the wrong value for the structure size, it returns a value that's too large.

Long story short, there's no general way to get an accurate value for the structure size programmatically. The best thing to do is to just not ask the question. Marshal.SizeOf() will give you a guesstimate, assuming the structure is blittable. If you need an accurate value for some reason then you could look at the generated machine code of a method that declares a local variable of the structure type and compare it to the same method without that local variable. You'll see the difference in the stack pointer adjustment, the "sub esp, xxx" instruction at the top of the method. Of course, it will be architecture dependent, you'll typically get a larger structure in 64-bit mode.

like image 142
Hans Passant Avatar answered Oct 14 '22 20:10

Hans Passant


You can use either the sizeof operator or SizeOf function.
There are some differences between those options, see the reference links for more.

Anyway a good way to use that function is to have a generic method or extension method like these:

static class Test {   static void Main()   {     //This will return the memory usage size for type Int32:     int size = SizeOf<Int32>();      //This will return the memory usage size of the variable 'size':     //Both lines are basically equal, the first one makes use of ex. methods     size = size.GetSize();     size = GetSize(size);   }    public static int SizeOf<T>()   {     return System.Runtime.InteropServices.Marshal.SizeOf(typeof(T));   }    public static int GetSize(this object obj)   {     return System.Runtime.InteropServices.Marshal.SizeOf(obj);   } } 
like image 28
Shimmy Weitzhandler Avatar answered Oct 14 '22 21:10

Shimmy Weitzhandler