Calculating the Size of Data Types in C using Sizeof

for loop cIn the C programming language, and several of the languages based on C, the sizeof operator can be used to calculate how many bytes a data type occupies in memory. This is particularly useful when working with structs and dynamic memory allocation using malloc, or when writing code that is intended to be portable between C compilers on various platforms. Certain data types may be a different size when compiled on different systems, and being able to detect this in your programs can help make the conversion an easier process.

In this explanation of the unary operator sizeof, very few of the other language features are described. Beginners may wish to start by learning the basics of C programming at Udemy.com before reading about the sizeof operator. A working knowledge of how memory is organized in a computer system may also be useful, and Computer Science for Everyone with Java introduces much of the background information that both C and Java programmers need.

Syntax and the Size of Basic Data Types

The basic data types in the C language (char, short, int, long, float, and double) may have different sizes depending on the implementation of the language that you are working with, and the size of the data bus in the central processing unit (CPU) of the target machine. The C language specification typically only sets the minimum size of these types.

You can use sizeof to return the exact size of these types:

/*
 *
 * Udemy.com
 * Calculating the Size of Data Types in C using Sizeof
 *
 */

#include <stdio.h>

void main() {
    printf("\r\nUdemy.com - Calculating the Size of Data Types in C using Sizeof\r\n\r\n");
    printf("Char: %u\r\n", sizeof(char));
    printf("Short: %u\r\n", sizeof(short));
    printf("Int: %u\r\n", sizeof(int));
    printf("Long: %u\r\n", sizeof(long));
    printf("Float: %u\r\n", sizeof(float));
    printf("Double: %u\r\n", sizeof(double));
}

Most implementations of C either return the value as an integer or, more commonly, as a size_t data type. Size_t values are automatically cast to other integer types when used.

Sizeof can also accept the name of a variable and will return the size of its underlying type. When using a variable, sizeof can usually be called either with parenthesis as in the example above, or without parenthesis as shown below:

void main() {
    int i = 0;
    printf("I: %u\r\n", sizeof i);
}

You should note that the C preprocessor, which is responsible for dealing with macros and preprocessor directives, has no understanding of types and so the sizeof operator cannot be used within directives like #if.

Structs

Depending on your system, the typical value returned by sizeof(char) will be 1 as the char type is usually stored as a single byte. The size of a structure containing three char types would, in theory, be 3. And on the compiler used to test the code in this tutorial, it is.

/*
 *
 * Udemy.com
 * Calculating the Size of Data Types in C using Sizeof
 *
 */

#include <stdio.h>

struct Test {
    char c1;
    char c2;
    char c3;
} myTest;

void main() {
    printf("Struct: %u\r\n", sizeof myTest);
}

You can calculate the size of a struct by passing a declared variable of that type as the argument to sizeof(), or by using the keyword struct in the call to sizeof(). For example: sizeof(struct Test).

In the first example, sizeof(short) returned 2 – a short is usually stored as a 16-bit number, made up of two bytes. So the size of a structure containing one short type and two char types should be 4. But it often isn’t.

/*
 *
 * Udemy.com
 * Calculating the Size of Data Types in C using Sizeof
 *
 */

#include <stdio.h>

struct Test {
    char c1;
    short s2;
    char c3;
} myTest;

void main() {
    printf("Struct: %u\r\n", sizeof(myTest));
}

If you use the C compiler from Microsoft Visual Studio with its default compiler settings, the size of this structure is 6 bytes, not 4. This is because of the struct packing that the compiler uses to make it more convenient for itself to work with structures. While packing can generally be changed using compiler directives, these are usually different for each compiler and so if you want your code to compile as-is on various compilers, you may need to rely on using sizeof() when allocating memory for structs, reading them from input streams, or writing them to output streams.

Arrays, Strings, and Pointers

Sizeof() can be used with arrays and C strings. However, it does not always work as you might expect. The size of an array is generally returned by sizeof() as the total number of bytes that it occupies. So an array containing 100 items of the type int (typically four bytes), will have a size of 400 bytes.

To calculate the length of the array (the number of items it contains), you can use the expression:

sizeof(array) / sizeof(array[0])

For example:

void main() {
    int buf[100];
    printf("Array Size: %u\r\n", sizeof(buf));
    printf("Array Length: %u\r\n", sizeof(buf) / sizeof(buf[0]));
}

Care must be taken when passing arguments to functions that use sizeof() to determine their size. If you use pointers and forget to add the dereferencing operator then sizeof() will return the size of a pointer, and not the size of the object it points to.

/*
 *
 * Udemy.com
 * Calculating the Size of Data Types in C using Sizeof
 *
 */

#include <stdlib.h>
#include <stdio.h>

typedef struct Test {
    char c1;
    char c2;
    char c3;
} myTest;

void main() {
    myTest *mTest;
    printf("\r\nUdemy.com - Calculating the Size of Data Types in C using Sizeof\r\n\r\n");
    mTest = (myTest*)malloc(sizeof(myTest));
    printf("Size of Pointer: %u\r\n", sizeof(mTest));
    printf("Size of Struct: %u\r\n", sizeof(*mTest));
    free(mTest);
}

Further Reading

In languages derived from C, such as C++ and Objective-C, the sizeof operator largely works on basic data types in the same way as described here. However, classes and objects will generally either be packed and padded in a similar fashion to C structs, or may actually be pointers. In either case, using the sizeof operator can be awkward and other functions or operators are usually provided to do the job.

The examples presented in this introduction are relatively basic, but involve the use of language features that beginners may not be familiar with. If any of the code samples are unclear, you can Learn C Programming at Udemy.com on a very comprehensive course that covers structs, dynamic memory management with malloc(), and the console output functions that have been used here.