7

I would like to deepen my understanding of data types and want to know how I can determine how big a data type is. I'm hoping the journey to the answer uncovers other unknowns.

I know that in .NET, a byte is an 8-bit unsigned integer, but only because I've read about it. If I have a very simple console app like the following:

static void Main(string[] args)
{
byte b = 1;
}

How can I tell in Visual Studio, how big the data structure of 'b' is? I see that there are some Memory diagnostic windows but it only says that they're unable to evaluate the expression when I step over the assignment of b. I have the Disassembly window open and can see the mov op...

mov         dword ptr [ebp-40h],1

... but not sure what the information means. I'm thinking that dword is hinting at the size and perhaps ptr ebp-40h is pointing to an address. Is there a way I can see all of the addresses in Visual Studio and perhaps glean the size by looking at the range?

I know these are tough questions to answer in a short forum like this but thanks for any help.

Joshua Belden
  • 10,273
  • 8
  • 40
  • 56

5 Answers5

9

You can use sizeof(T) to get the size of primitive value types and non-reference types. For other types, it can be very difficult to obtain the size, because reference types generally do not have a fixed size.

This can be a complex issue outside simple types (per the discussion below), but generally, if the size of a type is not defined explicitly by its data structures because it is itself a reference type, or it is a structure that contains reference types, then there is no way to calculate storage (since it is, by definition, not fixed).

Jamie Treworgy
  • 23,934
  • 8
  • 76
  • 119
  • Your answer is worded very poorly/misleadingly... it's incorrect as written (although people who already know the answer can see what you meant). – user541686 Jun 20 '12 at 19:05
  • It implies that if you embed a reference type inside a value type, then it'll have a fixed size. – user541686 Jun 20 '12 at 19:06
  • Huh? How do you embed a reference type in a value type? – Jamie Treworgy Jun 20 '12 at 19:07
  • 1
    `struct MyValueType { object o; }` --> `sizeof(MyValueType)`? – user541686 Jun 20 '12 at 19:07
  • 2
    Furthermore, not only will that not have a fixed size, but it *still* wouldn't *even if* you were simply embedding "primitive" types: `struct S { IntPtr p; }` certainly has a size (both managed and unmanaged), and it's not a fixed size either. – user541686 Jun 20 '12 at 19:09
  • OK, fair enough. I was trying to answer in as simple a way as possible since he was asking how to get the size of a primitive type, but I've updated it more explicitly. – Jamie Treworgy Jun 20 '12 at 19:12
  • Again, the second problem is still there -- `IntPtr` doesn't have a fixed size. The issue is a bit more subtle than you're thinking/implying -- it has **nothing** to do with whether the size is fixed. It has to do whether the type is managed or unmanaged, and whether it's blittable. – user541686 Jun 20 '12 at 19:14
  • 1
    Perhaps you should post a detailed answer that explains the nuances of platform-specific types? I believe that accuracy is important, but the OP was basically asking how to get the size of a `byte`. The answer he's looking for is, really, `sizeof`, and I tried (and failed) to explain in a few words why it wouldn't always work. I'll upvote a better answer. – Jamie Treworgy Jun 20 '12 at 19:21
  • Yea I did that a few minutes ago. :P – user541686 Jun 20 '12 at 19:27
  • jamietre, this is exactly what I was looking for, thank you. Mehrdad, thank you for being thorough, I now know there's more to look out and will keep going. – Joshua Belden Jun 20 '12 at 20:35
  • 1
    @Mehrdad, you definitely deserve this one. But I need the rep more :) – Jamie Treworgy Jun 21 '12 at 11:48
6

tl;dr: sizeof(YourType) should give you "the answer", but Marshal.SizeOf may be more appropriate.

Explanation:

That doesn't always work. C# doesn't like you breaking its abstraction barrier, so it only lets you find the "size" of a structure if the structure has the same size in managed and unmanaged code (or, more accurately, is "blittable"). Otherwise, C# claims, "why do you care about the managed size? It's useless to you", and doesn't let you take the sizeof of a managed type.

There are ways to get around this (through direct MSIL generation), but if you in fact want the size of the unmanaged representation of the same object, then you probably want to use Marshal.SizeOf instead. sizeof is actually not as useful as it seems -- it's just more handy.

Community
  • 1
  • 1
user541686
  • 205,094
  • 128
  • 528
  • 886
  • Thank you for this Mehrdad as well. I found this article to be helful in explaing this, http://www.codeproject.com/Articles/97711/sizeof-vs-Marshal-SizeOf. I'm not doing any unmanaged development, this was purely me trying to shake the .NET helping hand away. – Joshua Belden Jun 20 '12 at 20:40
3

There is also a hardcore SOS option, which will give you a true value for the size of an object.

Use !ObjSize command

==Immediate Window==
.load sos
!ObjSize <address>

You may need to poke around to get the address of the object. Check the !Dump* commands, like !DumpHeap and !DumpStack.

oleksii
  • 35,458
  • 16
  • 93
  • 163
1

I'm not sure if i understand it well, but there's an operator sizeof().

Console.WriteLine(sizeof(byte));

There's also an answer related to reference types: Getting the size of a field in bytes with C#

Community
  • 1
  • 1
nxu
  • 2,202
  • 1
  • 22
  • 34
1

I'm pretty sure that what you're asking for is how much memory a certain data type consumes? I would use the sizeof() method, so for:

int a = 2;

You could find how much space an int takes up with:

Console.WriteLine(sizeof(int);
rwhite
  • 69
  • 1
  • 10