What does sizeof do?
sizeof(x)
returns the amount of memory (in bytes) that the variable or type x
occupies. It has nothing to do with the value of the variable.
For example, if you have an array of some arbitrary type T
then the distance between elements of that array is exactly sizeof(T)
.
int a[10];
assert(&(a[0]) + sizeof(int) == &(a[1]));
When used on a variable, it is equivalent to using it on the type of that variable:
T x;
assert(sizeof(T) == sizeof(x));
As a rule-of-thumb, it is best to use the variable name where possible, just in case the type changes:
int x;
std::cout << "x uses " << sizeof(x) << " bytes." << std::endl
// If x is changed to a char, then the statement doesn't need to be changed.
// If we used sizeof(int) instead, we would need to change 2 lines of code
// instead of one.
When used on user-defined types, sizeof
still returns the amount of memory used by instances of that type, but it's worth pointing out that this does not necessary equal the sum of its members.
struct Foo { int a; char b; };
While sizeof(int) + sizeof(char)
is typically 5
, on many machines, sizeof(Foo)
may be 8
because the compiler needs to pad out the structure so that it lies on 4 byte boundaries. This is not always the case, and it's quite possible that on your machine sizeof(Foo)
will be 5, but you can't depend on it.
What does sizeof without () do?
So if we look at the grammar for sizeof
in the C99 draft standard section 6.5.3
Unary operators paragraph 1 it is as follows:
sizeof unary-expression
sizeof ( type-name )
There is a difference you can not use a type-name without parenthesizes and section 6.5.3.4
The sizeof operator paragraph 2 says(emphasis mine):
The sizeof operator yields the size (in bytes) of its operand, which may be an
expression or the parenthesized name of a type.[...]
For completeness sake you may wonder if we can use sizeof
with an expression if we have parenthesizes and the answer is yes since a unary-expression can itself contain parenthesizes. The easiest way to see this would be to look section A.2.1
Expressions from the draft standard and work through the grammar like so:
unary-expression -> postfix-expression -> primary-expression -> ( expression )
How Does sizeof(Array) work
sizeof(array)
is implemented entirely by the C compiler. By the time the program gets linked, what looks like a sizeof()
call to you has been converted into a constant.
Example: when you compile this C code:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
int a[33];
printf("%d\n", sizeof(a));
}
you get
.file "sz.c"
.section .rodata
.LC0:
.string "%d\n"
.text
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
pushl %ecx
subl $164, %esp
movl $132, 4(%esp)
movl $.LC0, (%esp)
call printf
addl $164, %esp
popl %ecx
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.2 (Gentoo 4.1.2 p1.1)"
.section .note.GNU-stack,"",@progbits
The $132
in the middle is the size of the array, 132 = 4 * 33. Notice that there's no call sizeof
instruction - unlike printf
, which is a real function.
What does sizeof(int**) mean?
sizeof(int **)
tells you how many bytes an int **
is, similarly to how sizeof(int *)
tells you how many bytes an int *
is. They just have different levels of indirection.
how and why sizeof(a)/sizeof(a[0]) in c is used to calculate the number of elements in an array
According to the C Standard (6.5.3.4 The sizeof and alignof operators)
2 The sizeof operator yields the size (in bytes) of its operand, which
may be an expression or the parenthesized name of a type. The size is
determined from the type of the operand. The result is an integer. If
the type of the operand is a variable length array type, the operand
is evaluated; otherwise, the operand is not evaluated and the result
is an integer constant.
So if you have an array as for example
int a[N];
where N is some integer value then expression
sizeof( a )
yields the number of bytes occupied by the array. As the array has N
elements and each element in turn occupies sizeof( int )
bytes then
sizeof( a ) == N * sizeof( int )
or what is the same
sizeof( a ) == N * sizeof( a[0] )
As result you can calculate N the following way
N = sizeof( a ) / sizeof( a[0] )
It is useful if you do not know the exact size of an array for example because its size depends on the number of initializers.
For example
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
Take into account that sometimes beginners make an error.
Let's assume that you have a function declaring an array as a parameter.
For example
void f( int a[10] );
and the function can be called like
int a[10];
f( a );
Beginners usually write in the body of the function the following expression
void f( int a[10] )
{
size_t n = sizeof( a ) / sizeof( a[0] );
//...
}
However it is a wrong code. The problem is that parameters declared like arrays are adjusted to pointers to the type of the array element. So the function declaration actually looks like
void f( int *a );
and within the function in expression
size_t n = sizeof( a ) / sizeof( a[0] );
parameter a
is pointer. That is it is equivalent to
size_t n = sizeof( int * ) / sizeof( int );
Depending on the used system pointers occupy either 4 or 8 bytes. So you will get either 2 or 1 if sizeof( int )
is equal to 4.
You will not get the number of elements in the array that was used as the argument.
Pointers do not keep an information about whether they point to a single object or the first object of some array.
In this case you should declare the function with second parameter that specifies the number of elements in the array. For example
void f( int *a, size_t n );
How do sizeof(arr) / sizeof(arr[0]) work?
If you have an array
then sizeof(array)
returns the number of bytes the array occupies. Since each element can take more than 1 byte of space, you have to divide the result with the size of one element (sizeof(array[0])
). This gives you number of elements in the array.
Example:
std::uint32_t array[10];
auto sizeOfInt = sizeof(std::uint32_t); // 4
auto numOfBytes = sizeof(array); // 10*sizeOfInt = 40
auto sizeOfElement = sizeof(array[0]); // sizeOfInt = 4
auto numOfElements = sizeof(array) / sizeof(array[0]); // numOfBytes / sizeOfElement = 40 / 4 = 10
LIVE EXAMPLE
Note that if you pass an array to a function, the above won't work since the array decays to a pointer and sizeof(array)
returns the size of the pointer.
std::size_t function(std::uint32_t a[]) // same for void function(std::uint32_t a[10])
{
return sizeof(a); // sizeof(std::uint32_t*)!
}
std::uint32_t array[10];
auto sizeOfArray = function(array); // array decays to a pointer inside function()
LIVE EXAMPLE #2
How does sizeof work? How can I write my own?
You haven't provided any meaningful details about what it is you want to do, so it is hard to figure out what you need.
You can "wrap" sizeof
by you own template function like
template <typename T> size_t my_sizeof() {
return sizeof(T);
}
and then use it as
size_t s = my_sizeof<int>();
From time to time one can come across a request to implement sizeof-like functionality without using sizeof
. Requests like that make no practical sense whatsoever, yet sometimes are used as homework assignments. One can probably do it as follows
template <typename T> size_t my_sizeof() {
T t;
return (char *) (&t + 1) - (char *) &t;
}
which would require a default-constructible T
. A less restricting but formally illegal solution (a hack) would be something like
template <typename T> size_t my_sizeof() {
return (char *) ((T *) NULL + 1) - (char *) (T *) NULL;
}
The above implementations implement type-based sizeof
.
An attempt to emulate the functionality of value-based sizeof
might look as follows
template <typename T> size_t my_sizeof(const T& obj) {
return my_sizeof<T>();
}
but this will not be even remotely equivalent to the built-in sizeof
, at least because the built-in sizeof
does not evaluate its argument.
Finally, neither of these implementations will produce integral constant expressions (ICE), as the built-in sizeof
does. Producing an ICE that way is impossible to achieve in the current version of the language.
In any case this all, of course, is totally devoid of any practical value. Just use sizeof
when you want to know the size.
What does sizeof(char *) do?
Because otherwise you would get the number of bytes that words array takes up, not the number of elements (char pointers are either 4 or 8 bytes on Intel architectures)
What does sizeof (function(argument)) return?
Except with variable length arrays, sizeof
does not evaluate its operand. So it will just yield the size of fun(a)
type, i.e. sizeof(int)
(without calling the function).
C11 (n1570) §6.5.3.4 The
sizeof
and_Alignof
operators2 [...] If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an
integer constant.
Related Topics
Rvalue to Lvalue Conversion Visual Studio
Why Sizeof(Int) Is Not Greater Than -1
How Is the C++ Exception Handling Runtime Implemented
Why Does the Enhanced Gcc 6 Optimizer Break Practical C++ Code
How to See the Assembly Code for a C++ Program
Default, Value and Zero Initialization Mess
C++ Templates Specialization Syntax
What Would Be C++ Limitations Compared C Language
How Boost::Function and Boost::Bind Work
Pimpl Idiom VS Pure Virtual Class Interface
Passing Shared Pointers as Arguments
In C++, Is It Still Bad Practice to Return a Vector from a Function
Lvalue to Rvalue Implicit Conversion
Replacing Ld with Gold - Any Experience
How to Make Reading from 'Std::Cin' Timeout After a Particular Amount of Time
G++ Does Not Show a 'Unused' Warning
Scope VS Life of Variable in C
Is There a Compiler Bug Exposed by My Implementation of an Is_Complete Type Trait