I've defined a struct to send via socket. I'd like to get the size of it but sizeof
is unsafe and the same for "System.Runtime.InteropServices.MarshalSizeOf
". Is there a way to get its size in a safe way?

- 2,707
- 19
- 43

- 33,370
- 43
- 136
- 210
-
Define safe. `Marshal.SizeOf` is perfectly safe as far as the CLR is concerned. – Noldorin Mar 10 '10 at 16:50
-
1Noldorin - Marshal.SizeOf requires UnSafe Code permission set to execute. This is the OP's issue – Mitchel Sellers Mar 10 '10 at 16:53
-
I tried System.Runtime.InteropServices.MarshalSizeOf(typeof(MyStruct)) and no "unsafe" anywhere and also unchecked the Allow unsafe code checkbox. It works fine to me now. ?????? – 5YrsLaterDBA Mar 10 '10 at 17:07
-
1If you send data via a socket, then it is unsafe to assume, that sender and receiver share the same platform and thus the same size. It would be safer to serialize and send first the size and then the result of a serialization. – weismat Nov 14 '12 at 04:29
-
`Marshal.SizeOf` will fail if the struct is a generic type. See http://www.informit.com/guides/content.aspx?g=dotnet&seqNum=728 for info and one way to get around the problem. – Jim Mischel Nov 14 '12 at 05:03
2 Answers
There is no way to do it for managed structs. Marshal.SizeOf
will only return the size of the data on the marshaled types that comprise the struct... that MIGHT be correct for the managed types on some platforms, but not on others.
This is by design so the JIT can lay structs differently depending on the platform it runs on.
More info here: Chris Brumme's blog

- 27,696
- 5
- 61
- 92
-
3The important question is why do you need to know the size of the struct? Odds are it's for an unsafe reason (in which case you can use `sizeof`) or it's for a P/Invoke (in which case `Marshal.SizeOf` is the correct answer). – Gabe Feb 11 '11 at 22:22
-
1Agreed. Was just trying to answer the original question: "why sizeof is unsafe and how to get size of a struct in a safe way?" :-) – Jcl Feb 11 '11 at 23:15
-
2One reason: you want to create an array of many structures and you need to know how many will fit into 2 GB. You need to know how much memory the runtime will allocate for the structure. – Jim Mischel Nov 14 '12 at 05:07
-
You might want to write the struct to file or a memory page. You need to know the size so you can calculate offsets, etc. – Mark Lauter Nov 26 '22 at 06:42
-
1@MarkLauter well, you can use `sizeof` then, but that's unsafe (as per definition of unsafe by the JIT, i.e., outside its memory-checking limits) if you want to write directly to a memory page or unserialized (direct from memory) data to a file... there's no problem using `sizeof` (or unsafe blocks, or pointers, or pinning), but you are stepping outside the "correctnes" and memory safety that the CLR provides on its "safe" blocks – Jcl Nov 26 '22 at 17:56
-
@Jcl yeah, I was responding to Gabe's "why do you need this" meme. BTW, when you say "there's no way to do this for managed structs" are you excluding the possibility of using StructLayout to specify the packing? I've used this in the past with pinning to read structured binary data from external sources. – Mark Lauter May 31 '23 at 01:47
-
@MarkLauter I'm saying that in response to the OP's question: "Is there a way to get its size in a safe way?"... yes, you can use an explicit layout and a specific packing (or `FieldOffset` attributes) and know the offsets of data, but I'd say the question would be different, and still, you'd only know the member offsets, not necessarily the size of it (which may be similar, but it's not strictly speaking, the same) – Jcl May 31 '23 at 09:57
-
See my blog post for a wrapper library that lets you determine what the JIT will define the managed type's size will be(at runtime). It works by using the sizeof
IL instruction which isn't exposed at all in C#. It can be run with no special permissions at all and is verifiable.
Note: this may or may not be what you actually want. This might return 8
for a structure that actually only has a single byte in it. I don't really understand your question completely, so I'm not sure if this is actually what you want or not.

- 62,085
- 98
- 303
- 499