# 2.3 — Variable sizes and the sizeof operator

As you learned in the lesson 2.1 -- Fundamental variable definition, initialization, and assignment, memory on modern machines is typically organized into byte-sized units, with each unit having a unique address. Up to this point, it has been useful to think of memory as a bunch of cubbyholes or mailboxes where we can put and retrieve information, and variables as names for accessing those cubbyholes or mailboxes.

However, this analogy is not quite correct in one regard -- most variables actually take up more than 1 byte of memory. Consequently, a single variable may use 2, 4, or even 8 consecutive memory addresses. The amount of memory that a variable uses is based on its data type. Fortunately, because we typically access memory through variable names and not memory addresses, the compiler is largely able to hide the details of working with different sized variables from us.

There are several reasons it is useful to know how much memory a variable takes up.

First, the more memory a variable takes up, the more information it can hold. Because each bit can only hold a 0 or a 1, we say that bit can hold 2 possible values.

2 bits can hold 4 possible values:

bit 0 bit 1
0 0
0 1
1 0
1 1

3 bits can hold 8 possible values:

bit 0 bit 1 bit 2
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1

To generalize, a variable with n bits can hold 2n (2 to the power of n, also commonly written 2^n) possible values. With an 8-bit byte, a byte can store 28 (256) possible values.

The size of the variable puts a limit on the amount of information it can store -- variables that utilize more bytes can hold a wider range of values. We will address this issue further when we get into the different types of variables.

Second, computers have a finite amount of free memory. Every time we declare a variable, a small portion of that free memory is used for as long as the variable is in existence. Because modern computers have a lot of memory, this often isn’t a problem, especially if only declaring a few variables. However, for programs that need a large amount of variables (eg. 100,000), the difference between using 1 byte and 8 byte variables can be significant.

The size of C++ basic data types

The obvious next question is “how much memory do variables of different data types take?”. You may be surprised to find that the size of a given data type is dependent on the compiler and/or the computer architecture!

C++ guarantees that the basic data types will have a minimum size:

Category Type Minimum Size Note
boolean bool 1 byte
character char 1 byte May be signed or unsigned
Always exactly 1 byte
wchar_t 1 byte
char16_t 2 bytes C++11 type
char32_t 4 bytes C++11 type
integer short 2 bytes
int 2 bytes
long 4 bytes
long long 8 bytes C99/C++11 type
floating point float 4 bytes
double 8 bytes
long double 8 bytes

However, the actual size of the variables may be different on your machine (particularly int, which is more often 4 bytes). In order to determine the size of data types on a particular machine, C++ provides an operator named sizeof. The sizeof operator is a unary operator that takes either a type or a variable, and returns its size in bytes. You can compile and run the following program to find out how large some of your data types are:

Here is the output from the author’s x64 machine (in 2015), using Visual Studio 2013:

```bool:           1 bytes
char:           1 bytes
wchar_t:        2 bytes
char16_t:       2 bytes
char32_t:       4 bytes
short:          2 bytes
int:            4 bytes
long:           4 bytes
long long:      8 bytes
float:          4 bytes
double:         8 bytes
long double:    8 bytes
```

Your results may vary if you are using a different type of machine, or a different compiler. Note that you can not take the sizeof the void type, since it has no size (doing so will cause a compile error).

If you’re wondering what ‘\t’ is in the above program, it’s a special symbol that inserts a tab (in the example, we’re using it to align the output columns). We will cover ‘\t’ and other special symbols when we talk about the char data type.

You can also use the sizeof operator on a variable name:

```x is 4 bytes
```

We’ll discuss the size of different types in the upcoming lessons, as well as a summary table at the end.

 2.4 -- Integers Index 2.2 -- Void

### 165 comments to 2.3 — Variable sizes and the sizeof operator

• Lorenzo

Hello!
If int is 2 bytes on one machine and 4 on the other, how can you use the same application on both machines? For example for storing value of 3 bytes. I don't see how would sizeof(int) help you here. It looks like I would always need to assume the smallest possible space for each type and use the appropriate type for my needs. By your table and my example, I would have to use long (since it is guaranteed that it is at least 4 bytes). Am I missing something here?

• Hi Lorenzo!

You can use @std::int_fast(8|16|32|64)_t. Those have a guaranteed minimum size.

References
<cstdint> - http://www.cplusplus.com/reference/cstdint/

• Lorenzo

Thanks!

• hello, please can one of you tell me exactly the size

• Jean Pi

Hi!
I understand that they're coded into a byte since that is the standard size of an element of memory.
But isn't that  huge waste of space? Since booleans can be coded on a single bit, that means 7 are going to waste. Is there any way we can avoid this, or use those bits for something useful?

Thanks for the great guide!

• Hi Jean!

> they're coded into a byte
Not necessarily. Every compiler developer can use however much memory they want to store a bool.

> But isn't that  huge waste of space?
Yes, but your processor is terrible at dealing with single-bit values. It's good at handling 8/16/32/64 bits. The waste of memory is not as bad as the waste of processing power when dealing with single bits.

> Is there any way we can avoid this
Use some other data type in combination with bitwise operators (covered later).

• Jean Pi

I see, thanks!

• R310

Hello,
Why did you use :\t\t" in that program?

• nascardriver

Hi R310!

'\t' is the escape character for a tab. Escape characters are covered in lesson 2.7.

• R310

Thank you!
That's a great website, how do I get to create an account :))?

• nascardriver

Registration is closed. The only active account is Alex'. You can however set an avatar on https://en.gravatar.com/ and it will show on learncpp.

• R310

Thanks.
How do you usually keep track of replies without subscription?

• nascardriver

I use the WordPress API to get notified about all new comments.

• R310

I don't get emails, that's very annoying...

• himanshu

Hi !
I want to know that is there any other small way to do this task'''

#include<iostream>
using namespace std;

int calculatecelcius()
{
cout<<"Enter fahrenheight ";
int f;
cin>>f;
return f-32;
}
float res()
{
float b=1.8;
return b;
}

float result()
{
float s=calculatecelcius();
float t=res();
cout<<"result is         :";
return s/t;
}
int main()
{

cout<< result()<<" degree celcius";

return 0;
}

• nascardriver

Hi himanshu!

* Use uniform initialization
* Don't use 'using namespace'
* Use double unless you're limited in memory

I assume you have to do this for school or something. Unless you've been instructed to use functions I'd just do the calculation in-line.

• himanshu

Why you used void in the main function?

• nascardriver

It doesn't have any effect in C++. I like to have it there to make clear that this function doesn't take any arguments and I didn't just forget to add parameters.

• himanshu

ok thanks

• Silviu

Hello.

"To generalize, a variable with n bits can hold 2n (2 to the power of n, also commonly written 2^n) possible values. With an 8-bit byte, a byte can store 28 (256) possible values."

Can you explain this phrase in a little more detail ? why 28 , 2^8 =256  and at the tables where 2 bits can hold 4 possible values and 3 bits can hold  8 possible values, i mean why ? Thanks

• nascardriver

Hi Silviu!

> and at the tables where 2 bits can hold 4 possible values
Let's say we have two bits, they can hold the values

That's 4 different values, if we add another bit we get 8 possible values

> why 28 , 2^8 =256
You have n dice and each dice has i sides, how many variations of laying down the dice are there?
Say n=1, i=6 (One six-sided dice)
How many variations are there? 6
You can show a 1, 2, 3, 4, 5 or 6, nothing else.

Say n=2, i=6 (Two six-sided dice)
How many variations are there? 36
Let dice B show number 1, dice A can show numbers 1 to 6, that's 6 different values.
Let dice B show number 2, dice A can show numbers 1 to 6, that's another 6 different values.
Let dice B show number 3, dice A can show numbers 1 to 6, that's another 6 different values.
...
You can show 6 * 6 values, that's 6^2

If you add another dice your previous two dice can show 36 values for each value dice C is showing, that's 6^2 * 6 = 6^3 values.

Change dice to anything and sides to anything, you'll always have i^n variations.
For bits i is 2 (A bit is 0 or 1) and n is the amount of bits.

• Silviu

thanks , now i understand .

2^3 =8 possible values
that's why is 2^n , i hope this is helpful for others and thank you.

• nascardriver

You seem to have understood it but I don't understand your examples at all.
You can add code tags around your examples to prevent the page from messing up your formatting.

• Silviu

i did it now , i hope others can understand

• nascardriver

That just made it worse, I guess this is what you intended to write

I still don't understand it though.

• Silviu

i don't know how to explain but this is one of my ways to see more clear (to test all the possibilities in bits using 0 and 1) so lets take the first example from 0 to 0 is 00
0 to 1 is 01
from 1 to 0 is 10
from 1 to 1 is 11

i hope i made myself clear and thank you.

• Cosmin

Hello! I have a question: given the below code, why doesn't it print the right answer for big values?

For low values, it prints the correct answer, but for big values, such as 1.000.000 it doesn't, although long long can contain such a big value.

• Alex

The issue is that you defined n as an int, so when you multiple n * (n + 1) this is done as an integer multiplication, not a long long multiplication.

If you change n to long long, or static_cast n to long long when you calculated Gauss_Sum, you will get the results you expect.

• Cosmin

Thank you, Alex!

hello alex sir,
in the above program,
[#include <iostream>

int main()
{
std::cout << "bool:\t\t" << sizeof(bool) << " bytes" << std::endl;
std::cout << "char:\t\t" << sizeof(char) << " bytes" << std::endl;
std::cout << "wchar_t:\t" << sizeof(wchar_t) << " bytes" << std::endl;
std::cout << "char16_t:\t" << sizeof(char16_t) << " bytes" << std::endl; // C++11, may not be supported by your compiler
std::cout << "char32_t:\t" << sizeof(char32_t) << " bytes" << std::endl; // C++11, may not be supported by your compiler
std::cout << "short:\t\t" << sizeof(short) << " bytes" << std::endl;
std::cout << "int:\t\t" << sizeof(int) << " bytes" << std::endl;
std::cout << "long:\t\t" << sizeof(long) << " bytes" << std::endl;
std::cout << "long long:\t" << sizeof(long long) << " bytes" << std::endl; // C++11, may not be supported by your compiler
std::cout << "float:\t\t" << sizeof(float) << " bytes" << std::endl;
std::cout << "double:\t\t" << sizeof(double) << " bytes" << std::endl;
std::cout << "long double:\t" << sizeof(long double) << " bytes" << std::endl;
return 0;
}]
if in place of [int main()] i use [void main()],
it should return the same output but it doesn't. can you please tell why so?

• Alex

Having main return void is technically illegal, though some compilers allow it.

I'm not sure what you mean by "it should return the same output but it doesn't". How are you validating what output it is returning, and what are you seeing?

• ebra

hello , thanks for all the amazing work you've done , i just have one problem with sizeof() , for example
string A ;
a="hello";
cout<<sizeof(a);
cout<<sizeof("hello") should i put the size by counting tge letters and adding 1 or by the table
i know how to determine the size of bool float etc but i cant seem to know how to measure the size of othrr variables numbers or etc .. for example "h2o" "hello" i hope someone can help me . thanks

• Alex

std::string is a class that allocated dynamic memory to hold its contents. sizeof() is resolved by the compiler and will only return the size of non-dynamic elements. So taking the sizeof a std::string won't return what you're expecting. For a string literal ("hello") it will return the size of the array holding the string contents (array length * element size), which will equal the length of the string since the elements are chars and sizeof(char) is 1.

That's probably a confusing answer at this point, as it touches on a lot of topics we haven't covered yet. In general, as long as you stick to taking the sizeof() variables or literals of fundamental types (int, float, etc...) you'll be fine. Once you dig into other topics (arrays, pointers, classes, etc...) the reason why sizeof works like it does for those will become more clear.

• Elvin Belvin

"Interestingly, the sizeof operator is one of only three operators in C++ that are a word instead of a symbol. The other two are new and delete."

There are plenty more
binary bit operators

and a few more.

unary

I would argue that those are word operators too. Some of them have symbolic representation.
Or am I misunderstanding something?

• Alex

Interesting point about the alternative operators. I'd forgotten about those, because they're really just provided for C compatibility on machines that aren't ASCII compatible. Throw isn't an operator, it's a keyword. But I've removed the sentence overall, as it's no longer true post C++11.

• Elvin Belvin

In the section 3.1 Operator precedence and associativity, there is a table of operators. Throw is listed as an operator with precedence 16.

• Alex

Yes, and you'll see similar tables on other sites. Throw is in the table to make it clear that it takes precedence over comma. But it's not actually an operator itself. The C++ standard isn't very consistent on the definitions of operators vs keywords, so I wouldn't worry about it.

• My dear Teacher,
Please let me say that in first sentence you give link  at "2.1 -- basic addressing and variable definition". Actually link is at "2.1 — Fundamental variable definition, initialization, and assignment". Same typo occurs in next lesson "2.4 — Integers", subsection "Overflow".
With regards and friendship
Georges Theodosiou

• Alex

Fixed! Thanks for pointing out the inconsistency.

• lnm

Hi Alex, can we declear a 16 bytes integer or more, if yes tell me how 🙂

• Alex

No. If you want to do this, you'll need to use a custom class that handles large integers.

• lnm

yep, but how, can u tell me the that class that support larger integer have equipped with mathematical operator. By far, I only know how to use string to perform "+,-,*,/,%". What I have realize is a char that store 1 digit (0-->9) while char can store (0 --> 127), so how wasteful it is.

• Alex

Sorry, I'm not sure what you're asking here.

• lnm

what I mean here, I use a function like
char[1000] sum(&char[1000] a , &char[1000] b)
{
//code goes here
return ...;
};
blah blah ...
so what I mean here : can you illustrate how to use a custom class that handles large integers. ( not by string.)

• Alex

If the class is designed appropriately, you should be able to use it in the same way you'd use a normal integer, as it should come with overloaded operators that perform arithmetic operations.

If you're asking me how to write such a class in the first place, that's outside the scope of these tutorials.

• ronald

if you define a variable in lets say main function then you call for another function then when the called function has finished executing it returns control back to main does the defined variable still stays there or does it get destroyed

• Alex

It still exists because the block the variable was defined in didn't end yet (it was just interrupted to call another function).

• Le Thu Ha

Hi Alex,
I went through your tutorial but could not find enough details of how can we calculate sizeof a class. I have read somewhere that it would take into account member function as well as varriable, but not static member varriable. And also it is double for virtual member function since it is written into a V-Table ... Have you written those details somewhere and I missed it? Thank you very much for sharing!

• Alex

I don't think I ever cover this as a discrete topic -- all the pieces are there, but I don't connect the dots.

Basically, the size of a class is related to:
* The size of each non-static member variable (this includes inherited members)
* Whether or not there's a virtual pointer (which adds one pointer worth of size)
* Whether there's any padding or alignment between the members

Any dynamic memory allocated is not included by sizeof().

The first two items are fairly easy to manually calculate. The third is a little more tricky.

• Le Thu Ha

Thank you!
This problem is quite interesting since it is memory effectioncy when software architecture/developer design classes. Do you know a good document about this topic?

• Alex

Nope. 🙁

• McSteven

Please, When you say "the sizeof operator is one of only three operators in C++ that are a word instead of a symbol. The other two are new and delete", do you mean symbols like what?

• Alex

symbols like +, [], (), &, etc...

• darshan

may i know sizeof(register) and register operation

• Alex

There's no way to access the CPU's registers directly in C++, so unless register is something else, this isn't possible.

• Alan

Hi, Alex.

After I read "Note that you can not take the sizeof the void type, since it has no size (doing so will cause a compile error).", I tried on my Code::Blocks, and it turned out that the compiler just showed a warning, no compile errors. When I tried to print the value of sizeof(void), it showed 1. I googled it and thought that maybe it is compiler-dependent?

• Alex

It's compiler dependent only in the sense that some compilers don't follow the C++ standard like they should. Taking the sizeof(void) should be an error. Some compilers return 1 instead -- I'm not sure why, but this is non-standard behavior.

• James Ray

Hi Alex,

If you CTRL+F in this article for "However, you may find on your system that the variables are larger (particularly for int, which is often 4 bytes)." I think you will see that this might be best to be omitted or moved, as you later say (after the table of minimum byte size of data types): "However, the actual size of the variables may be different on your machine."

• Alex

Thanks, good suggestion. I've removed the redundant line.

• James Ray

You're welcome!

• Dion

Hey Alex. No question here, just... Thanks for all of the time you've put into this website. Thanks for the calm and friendly manner in which you've answered so many often blunt, rude, arrogant, or repetitive comments. I'm learning a lot here, and I expect it'll have a large and positive impact on my life. So, thanks.

• Alex

You're welcome, thanks for letting me know you're enjoying the site!

I try to keep in mind that a lot of the readers here don't speak English as their primary language. So what may seem rude or blunt to a native speaker (like me) probably isn't intentional.

• McSteven

Yeah, you're right. Me , I a french native speaker.

• kundan

i mean sizeof() operaror

• Alex

sizeof() isn't used very often. It's mainly used in two cases that I'm aware of:
* With asserts, to ensure your data types are the size you expect them to be (e.g. if you assume anywhere that int is 4 bytes, you'd best assert that sizeof(int) >= 4)
* With fixed arrays, as a "hacky" way to get the array's length.

I use it here more as a way to teach that variables use different amounts of bytes, so you can see it for yourself.

• kundan

where is it used?

• Alex

Where is what used?

• #include<iostream>
using namespace std;
struct student
{
int rollno;
char name[10];
float percentage;
int subone;
};
int main()
{ struct student s;
cout<<sizeof(s)<<endl;
}

the size of structure if size of char variable is 8, then it print 20
& for 9,10,11,12 it print 24;
why????

• Alex

• Matt

Why does putting two tabs align the output colums?

• Alex

\t moves the cursor to the next tab stop, which is every 8 characters by default.

• g++ -std=c++
(default Code::Blocks compiler)

bool:           1 bytes
char:           1 bytes
wchar_t:        2 bytes
char16_t:       2 bytes
char32_t:       4 bytes
short:          2 bytes
int:            4 bytes
long:           4 bytes
long long:      8 bytes
float:          4 bytes
double:         8 bytes
long double:    12 bytes

The more you know!

• Brian Gaucher

g++ using terminal

• Mauricio Mirabetti

Alex,
First, I guess "There are several reasons it is useful to know how much memory a variable takes up." is missing a "why" between "reasons" and "it". Although I'm not a native english speaker (Brazilian living in Brazil), I thought such an excellent tutorial deserves all the help it can get.
Second, besides learning really well all the fundamentals of C++ (I started with Cobol early in the days, and never stopped to really learn C++ properly) with these amazing work, I laugh my a** off with some of your comments (like the one about mixing cases on variable names and to have someone's head examined =D).
Sorry for such a poor contribution. And thanks for all my heart. Hope I can contribute and support with your work soon.
Best regards.

Mauricio

• Alex

Actually, it's grammatically correct either way (with or without the why). Thanks for visiting!

• Ganesh

In some books author has use <climits> header.is it necessary to mention or its optional.

• Alex

The climits header defines a bunch of macro constants that indicate the minimum and maximum values for certain data types. This can be useful in some rare cases but personally I almost never use them. You could use them to do something like this:

• Jonas

Are variable sizes important to learn?
I hit the wall and have gone back a few steps to try to catch up with the tutorial again, but I feel like there is a lot of stuff coming.
I only intend to create pretty simple programs, and most like for simple games, so I don't know if sizes are required at the moment.
If it turns out that it is, I will of course try to learn the numbers, but I'm not that effective at that kind of learning, as in reading and remembering.

• Alex

It's not as important that you remember the specific sizes as it is that you remember that variables have sizes and what the ramifications are of trying to put more data in those variables than they can hold.

You can always look up the specific numbers if you find yourself in a situation where that's relevant/important.

• Michael Johnson

GRAMMAR

I'm a grammar nazi, so it made me sad when I came across this:

"The amount of memory that a variable uses is based on it’s data type."

it's --> its

• Alex

Fixed.

• Dyablo

Hi, I love the guide, it's a great help for me.
I use code::blocks for coding and to make sure it supported C++11, I had it output a value that I had brace-initialized.
It worked, implying support.  However, when I tried the code from this lesson with char16_t and char32_t, I get an undeclared error.
Any help?

• Alex

Make sure you have C++11 support turned on. There's a guide on how to do so in lesson 0.5 — Installing an Integrated Development Environment (IDE).

• Lucas Wolschick

You should make that link visible in the introduction of the IDEs, I had a hard time finding it

• Alex

Good call. I've now integrated that directly into lesson 0.5, where the IDE's are being setup.

• Samuel Kurland

I love this guide. Thanks so, so much for it.

Just a very small nitpicky correction: "Interestingly, the sizeof operator is one of only three operators in C++ that is a word instead of a symbol" should be "Interestingly, the sizeof operator is one of only three operators in C++ that <b>are</b> words instead of symbols."