The sizeof operator, returns the size of an expression, or of an object type in C. An expression is for example 1 + 2, an object is any region of memory, and a type is for example int. The value returned by the sizeof operator, is of type size_t, and its unit is byte. Show size_t is an unsigned integer type, which is defined in the stddef.h header. It can hold any value returned by the sizeof operator, and has a min value of 0, and a max value of the largest value, that can be returned by the sizeof operator. size_t can for example be defined as: typedef unsigned long size_t;The sizeof operator returns 1, meaning 1 byte, when used with the char, unsigned char, or signed char types. The number of bits in a char, is defined in the limits.h header, using the macro CHAR_BIT. #define CHAR_BIT 8The following example illustrates, how to get the number of bits for other types. #include <stdio.h> /* include the stdio.h header, in order to use printf, to print formatted strings .*/ #include <limits.h> /* include the limits.h header, to use CHAR_BIT, which defines the number of bits, that the char type can have .*/ int main( int argc, char * argv[ ] ) { printf( "sizeof( int ) is: %lu bytes\n", sizeof( int )); /* output: sizeof( int ) is: 4 bytes .*/ printf( "size of int in bits is: %lu bits\n", sizeof( int ) * CHAR_BIT ); /* output: size of int in bits is: 32 bits .*/ return 0;}sizeof and structuresWhen sizeof is used with a structure, it returns the size of the elements in this structure, with any padding. Padding will happen, when the size of the structure is not a multiple of the size of the largest element in this structure. A structure is padded with bits, that don’t have any specific value, till it has a size which is a multiple of the largest element in this structure. Padding happens to have faster access to the structure elements, and because sometimes some cpu architecture don’t support access to non aligned memory. #include <stdio.h> /* include the stdio header to use the printf function .*/ struct aPaddedStruct{ char aChar; // aChar has a size of 1 int anInt; /* anInt has a size of 4 bytes .*/ }; /* The size of aPaddedStruct is 8 instead of 5, since the size of the largest element in this struct is 4 bytes .*/ int main( int argc , char * argv[ ] ){ printf( "sizeof( struct aPaddedStruct ) is: %lu", sizeof( struct aPaddedStruct )); // sizeof( struct aPaddedStruct ) is: 8 return 0; }If the last element of a structure is an array, which size is not defined, then sizeof will return the size of the structure, without the array size. #include<stdio.h> /* include the stdio header, to use the printf function .*/ struct aStruct{ short aShort; /* size of short is 2 bytes .*/ char aCharOne; // size of char is 1 char aCharTwo; // size of char is 1 int anIntArray[ ]; /* anIntArray doesn't have a size, because it does not define the number of elements it has.*/ }; // size of aStruct is 4 int main( int argc, char *argv[ ] ){ printf( "sizeof( aStruct ) is: %lu", sizeof( struct aStruct )); /*output : sizeof( aStruct ) is: 4 */ return 0; }sizeof and unionssizeof returns the size of the largest element in a union. A compiler might add padding to a union, so that its size, will be a multiple of the size of the largest element, in this union. This is used to allow faster access, or because some cpu architecture, don’t allow access to non aligned boundaries. #include <stdio.h> /* include the stdio header, to use the printf function .*/ struct _aStruct{ int anIntOne; // size of an int is 4 short aShort; // size of a short is 2 int anIntTwo; /* size of an int is 4 .*/ }; /* The size of _aStruct is 12, since it is padded to the size of its largest element, which is an int .*/ union aUnion{ struct _aStruct aStruct; // size of struct _aStruct is 12 long aLong; /* size of long is 8 .*/ }; /* The size of the largest element in this union is long. The union is padded to the size of its largest element, hence it has a size of 16 .*/ int main( int argc, char * argv[ ] ){ printf( "The size of aUnion is: %lu\n", sizeof( union aUnion )); /*output: the size of aUnion is: 16 */ return 0;}sizeof and arraysWhen using sizeof with an array, it will return the size of all the elements in the array. #include <stdio.h> /* include the stdio header, to use the printf function .*/ int main( int argc, char * argv[ ] ){ int anIntArray[ 22 ]; /* anIntArray has a size of the size of the int type, multiplied by 22. so it has a size of 4 * 22 = 88 bytes .*/ printf( "sizeof( anIntArray ) is: %lu\n" , sizeof( anIntArray )); // sizeof( anIntArray ) is: 88 char aCharArray[ 3 ]; /* aCharArray has a size of the size of the char type, multiplied by 3 . so it has a size of 1 * 3 = 3 bytes .*/ printf( "sizeof( aCharArray ) is: %lu\n" , sizeof( aCharArray )); // sizeof( aCharArray ) is: 3 return 0;}sizeof can be used to calculate the number of elements in an array, by dividing the size of the array, by the size of an element in the array. sizeof and pointersA pointer is simply an address which is stored in memory, as such it has a size. The sizeof operator, can be used to get the size of a pointer. There is no defined size of a pointer in C, it is defined by the implementation, usually on a 32 bits machine, a pointer has a size of 32 bits, and on a 64 bits machine, a pointer has a size of 64 bits. #include <stdio.h> /* include the stdio header, to use the printf function .*/ int main(int argc, char * argv[ ]){ printf("sizeof( void * ) is %lu\n", sizeof (void * )); // sizeof( void * ) is 8 printf( "sizeof( char * ) is %lu\n", sizeof( char * )); // sizeof( char * ) is 8 return 0;}sizeof and other object typesAn object is just a memory region, so it has an allocated size. The object types in C are:
sizeof and expressionssizeof expression sizeof( expression )An expression is simply a combination of operands and operators, whatever these operand or operators are. When using the sizeof operator with an expression, the parenthesis () can be used or skipped . #include <stdio.h> /* include the stdio header, to use the printf function .*/ int sum( int x, int y ){ /* return the sum of x and y */ return x + y; } int main( int argc, char * argv[ ] ){ int anInt = 1; printf( "sizeof anInt is: %lu \n", sizeof anInt ); // sizeof anInt is: 4 double aDouble = 3.0; printf( "sizeof aDouble is: %lu \n", sizeof aDouble ); // sizeof aDouble is: 8 printf( "sizeof( aDouble + anInt ) is: %lu \n", sizeof( aDouble + anInt )); // sizeof( aDouble + anInt ) is: 8 printf( "sizeof( 3.0f + 1 ) is: %lu \n", sizeof( 3.0f + 1 )); /* 3.0f is a float 3.0f + 1 = 4.0f 4.0f is a float sizeof( float ) is 4 Output: sizeof (3.0 + 1) is: 4 .*/ printf( "sizeof sum( 1, 5 ) is: %lu \n", sizeof sum( 1, 5 )); // sizeof sum( 1, 5 ) is: 4 printf( "sizeof 100 is: %lu \n", sizeof 100 ); // sizeof 100 is: 4 return 0;}sizeof cannot be applied?The sizeof operator, cannot be applied to a non object type, such as a function, or to an incomplete type. An incomplete type, is a type which is declared but not yet defined, or a type which doesn’t have a size, such as the void type. struct incompleteTypeStruct; /* struct incompleteTypeStruct is declared but is not yet defined , as such it is an incomplete type .*/ enum incompleteTypeEnum; /* enum incompleteTypeEnum is declared but is not yet defined, as such it is an incomplete type .*/ int anIntarray[ ]; /* anIntarray size is not defined, as such it is an incomplete type .*/ int main( int argc, char * argv[ ] ){ sizeof( struct incompleteTypeStruct ); sizeof( enum incompleteTypeEnum ); sizeof( anIntarray ); sizeof( void ); /* These statements will cause an error, since they are trying to get the size of incomplete types .*/ return 0;} |