Coming Soon
This lesson is currently being developed
Object sizes and the sizeof operator
Learn to determine the size of data types and objects.
What to Expect
Comprehensive explanations with practical examples
Interactive coding exercises to practice concepts
Knowledge quiz to test your understanding
Step-by-step guidance for beginners
Development Status
Content is being carefully crafted to provide the best learning experience
Preview
Early Preview Content
This content is still being developed and may change before publication.
4.3 — Object sizes and the sizeof operator
In this lesson, you'll learn how much memory different data types use and how to determine the size of any object using the sizeof
operator.
Why does size matter?
Every variable and object in C++ occupies a specific amount of memory. Understanding sizes is important because:
- Memory efficiency: Choose appropriate types to avoid wasting memory
- Performance: Smaller types can be processed faster
- System compatibility: Size requirements may vary between systems
- Array and memory calculations: Essential for working with arrays and dynamic memory
Think of memory like a parking lot where different vehicles need different amounts of space - a motorcycle needs less space than a truck!
The sizeof operator
The sizeof
operator tells you how many bytes an object or data type occupies in memory:
sizeof(type) // Size of a data type
sizeof(variable) // Size of a variable
Basic sizeof usage
#include <iostream>
int main()
{
// Check sizes of fundamental data types
std::cout << "Fundamental type sizes (in bytes):\n";
std::cout << "char: " << sizeof(char) << std::endl;
std::cout << "bool: " << sizeof(bool) << std::endl;
std::cout << "int: " << sizeof(int) << std::endl;
std::cout << "float: " << sizeof(float) << std::endl;
std::cout << "double: " << sizeof(double) << std::endl;
std::cout << "long long: " << sizeof(long long) << std::endl;
return 0;
}
Typical Output: (sizes may vary by system)
Fundamental type sizes (in bytes):
char: 1
bool: 1
int: 4
float: 4
double: 8
long long: 8
Using sizeof with variables
#include <iostream>
int main()
{
// Create variables of different types
char letter = 'A';
int age = 25;
double price = 19.99;
long long bigNumber = 9876543210LL;
// Check size of variables
std::cout << "Variable sizes:\n";
std::cout << "letter (char): " << sizeof(letter) << " bytes\n";
std::cout << "age (int): " << sizeof(age) << " bytes\n";
std::cout << "price (double): " << sizeof(price) << " bytes\n";
std::cout << "bigNumber (long long): " << sizeof(bigNumber) << " bytes\n";
return 0;
}
Output:
Variable sizes:
letter (char): 1 bytes
age (int): 4 bytes
price (double): 8 bytes
bigNumber (long long): 8 bytes
Data type size guarantees
C++ provides certain size guarantees for fundamental types:
Size relationships
#include <iostream>
int main()
{
std::cout << "Size relationships in C++:\n";
// These relationships are guaranteed by the C++ standard
std::cout << "sizeof(char) = " << sizeof(char) << " (always 1 byte)\n";
std::cout << "sizeof(short) = " << sizeof(short) << " (>= 2 bytes)\n";
std::cout << "sizeof(int) = " << sizeof(int) << " (>= 2 bytes)\n";
std::cout << "sizeof(long) = " << sizeof(long) << " (>= 4 bytes)\n";
std::cout << "sizeof(long long) = " << sizeof(long long) << " (>= 8 bytes)\n";
// Verify relationships
std::cout << "\nVerifying size relationships:\n";
std::cout << "sizeof(char) <= sizeof(short): " << (sizeof(char) <= sizeof(short)) << std::endl;
std::cout << "sizeof(short) <= sizeof(int): " << (sizeof(short) <= sizeof(int)) << std::endl;
std::cout << "sizeof(int) <= sizeof(long): " << (sizeof(int) <= sizeof(long)) << std::endl;
std::cout << "sizeof(long) <= sizeof(long long): " << (sizeof(long) <= sizeof(long long)) << std::endl;
return 0;
}
Typical Output:
Size relationships in C++:
sizeof(char) = 1 (always 1 byte)
sizeof(short) = 2 (>= 2 bytes)
sizeof(int) = 4 (>= 2 bytes)
sizeof(long) = 8 (>= 4 bytes)
sizeof(long long) = 8 (>= 8 bytes)
Verifying size relationships:
sizeof(char) <= sizeof(short): 1
sizeof(short) <= sizeof(int): 1
sizeof(int) <= sizeof(long): 1
sizeof(long) <= sizeof(long long): 1
Key guarantees
- char is always 1 byte (by definition, a byte is the size of char)
- Size ordering:
char ≤ short ≤ int ≤ long ≤ long long
- Minimum sizes:
short
: at least 16 bits (2 bytes)int
: at least 16 bits (2 bytes)long
: at least 32 bits (4 bytes)long long
: at least 64 bits (8 bytes)
Platform differences
Sizes can vary between different systems and compilers:
#include <iostream>
#include <climits> // For CHAR_BIT
int main()
{
std::cout << "System information:\n";
std::cout << "Bits per byte: " << CHAR_BIT << std::endl;
// Calculate bits for each type
std::cout << "\nType sizes in bits:\n";
std::cout << "char: " << sizeof(char) * CHAR_BIT << " bits\n";
std::cout << "int: " << sizeof(int) * CHAR_BIT << " bits\n";
std::cout << "long: " << sizeof(long) * CHAR_BIT << " bits\n";
std::cout << "long long: " << sizeof(long long) * CHAR_BIT << " bits\n";
std::cout << "float: " << sizeof(float) * CHAR_BIT << " bits\n";
std::cout << "double: " << sizeof(double) * CHAR_BIT << " bits\n";
return 0;
}
Typical Output:
System information:
Bits per byte: 8
Type sizes in bits:
char: 8 bits
int: 32 bits
long: 64 bits
long long: 64 bits
float: 32 bits
double: 64 bits
Practical examples of sizeof
Memory usage calculations
#include <iostream>
int main()
{
// Calculate memory usage for different scenarios
int numStudents = 1000;
std::cout << "Memory usage for storing data of " << numStudents << " students:\n";
std::cout << "Student IDs (int): " << numStudents * sizeof(int) << " bytes\n";
std::cout << "GPAs (double): " << numStudents * sizeof(double) << " bytes\n";
std::cout << "Pass/Fail status (bool): " << numStudents * sizeof(bool) << " bytes\n";
// Total memory
int totalMemory = numStudents * (sizeof(int) + sizeof(double) + sizeof(bool));
std::cout << "Total memory: " << totalMemory << " bytes (" << totalMemory / 1024 << " KB)\n";
return 0;
}
Output:
Memory usage for storing data of 1000 students:
Student IDs (int): 4000 bytes
GPAs (double): 8000 bytes
Pass/Fail status (bool): 1000 bytes
Total memory: 13000 bytes (12 KB)
Choosing appropriate types based on size
#include <iostream>
#include <climits>
int main()
{
std::cout << "Choosing types based on requirements:\n\n";
// Age: 0-150 years - can use small type
std::cout << "For age (0-150):\n";
std::cout << "unsigned char max value: " << static_cast<int>(UCHAR_MAX) << std::endl;
std::cout << "unsigned char size: " << sizeof(unsigned char) << " byte\n";
std::cout << "int size: " << sizeof(int) << " bytes\n";
std::cout << "Recommendation: Use unsigned char to save memory\n\n";
// Population: Could be in billions
std::cout << "For world population:\n";
std::cout << "int max value: " << INT_MAX << std::endl;
std::cout << "long long max value: " << LLONG_MAX << std::endl;
std::cout << "Recommendation: Use long long for safety\n\n";
// Precision requirements
std::cout << "For precision requirements:\n";
std::cout << "float size: " << sizeof(float) << " bytes (about 7 decimal digits)\n";
std::cout << "double size: " << sizeof(double) << " bytes (about 15 decimal digits)\n";
std::cout << "Recommendation: Use double for most calculations\n";
return 0;
}
Working with array sizes
Understanding sizeof is crucial when working with arrays:
#include <iostream>
int main()
{
// Array examples
int numbers[10];
double prices[5] = {19.99, 29.99, 9.99, 15.50, 99.99};
char message[100];
std::cout << "Array sizes:\n";
std::cout << "numbers array: " << sizeof(numbers) << " bytes\n";
std::cout << "prices array: " << sizeof(prices) << " bytes\n";
std::cout << "message array: " << sizeof(message) << " bytes\n";
// Calculate number of elements
std::cout << "\nNumber of elements:\n";
std::cout << "numbers has " << sizeof(numbers) / sizeof(numbers[0]) << " elements\n";
std::cout << "prices has " << sizeof(prices) / sizeof(prices[0]) << " elements\n";
std::cout << "message can hold " << sizeof(message) / sizeof(message[0]) << " characters\n";
return 0;
}
Output:
Array sizes:
numbers array: 40 bytes
prices array: 40 bytes
message array: 100 bytes
Number of elements:
numbers has 10 elements
prices has 5 elements
message can hold 100 characters
Common sizeof mistakes
❌ Assuming sizes are the same on all systems
// Bad: Hard-coding sizes
void processData()
{
// Don't assume int is always 4 bytes!
char buffer[4]; // Might not be enough for an int on all systems
}
✅ Using sizeof for portable code
#include <iostream>
void processData()
{
// Good: Use sizeof to determine size
char buffer[sizeof(int)]; // Always correct size for int
std::cout << "Buffer size: " << sizeof(buffer) << " bytes\n";
}
❌ Using sizeof with function parameters
#include <iostream>
// This function has a problem!
void printArraySize(int arr[])
{
// This does NOT give the array size!
// It gives the size of a pointer (usually 8 bytes on 64-bit systems)
std::cout << "Array size: " << sizeof(arr) << " bytes\n"; // Wrong!
}
int main()
{
int numbers[10];
std::cout << "Actual array size: " << sizeof(numbers) << " bytes\n";
printArraySize(numbers); // This will show wrong size!
return 0;
}
Output:
Actual array size: 40 bytes
Array size: 8 bytes
✅ Correct way to work with array sizes
#include <iostream>
// Pass size as separate parameter
void printArrayInfo(int arr[], size_t size)
{
std::cout << "Array has " << size << " elements\n";
std::cout << "Each element is " << sizeof(arr[0]) << " bytes\n";
std::cout << "Total size would be " << size * sizeof(int) << " bytes\n";
}
int main()
{
int numbers[10];
size_t arraySize = sizeof(numbers) / sizeof(numbers[0]);
printArrayInfo(numbers, arraySize);
return 0;
}
Memory efficiency considerations
Understanding sizes helps you write efficient code:
#include <iostream>
// Inefficient: Uses too much memory
struct BadStudentRecord
{
long long id; // 8 bytes (but student ID fits in int)
double age; // 8 bytes (but age fits in unsigned char)
long long grade; // 8 bytes (but grade 0-100 fits in unsigned char)
};
// Efficient: Uses appropriate types
struct GoodStudentRecord
{
int id; // 4 bytes (sufficient for student ID)
unsigned char age; // 1 byte (sufficient for age 0-255)
unsigned char grade; // 1 byte (sufficient for grade 0-100)
// Note: Compiler may add padding, but still more efficient
};
int main()
{
std::cout << "Memory usage comparison:\n";
std::cout << "BadStudentRecord: " << sizeof(BadStudentRecord) << " bytes per student\n";
std::cout << "GoodStudentRecord: " << sizeof(GoodStudentRecord) << " bytes per student\n";
int numStudents = 10000;
std::cout << "\nFor " << numStudents << " students:\n";
std::cout << "Bad approach: " << sizeof(BadStudentRecord) * numStudents << " bytes\n";
std::cout << "Good approach: " << sizeof(GoodStudentRecord) * numStudents << " bytes\n";
return 0;
}
Output:
Memory usage comparison:
BadStudentRecord: 24 bytes per student
GoodStudentRecord: 8 bytes per student
For 10000 students:
Bad approach: 240000 bytes
Good approach: 80000 bytes
Summary
The sizeof
operator is essential for understanding memory usage in C++:
- sizeof returns the size in bytes of a type or variable
- char is always 1 byte by definition
- Type sizes have minimum guarantees but can vary between systems
- Use sizeof for portable code instead of hard-coding sizes
- Choose appropriate types to balance memory efficiency and value range
- sizeof with arrays gives total size, not number of elements
- Be careful with function parameters - sizeof doesn't work as expected
Understanding memory sizes helps you write more efficient and portable C++ programs.
Quiz
- What does the
sizeof
operator return? - Which fundamental data type is guaranteed to be exactly 1 byte?
- Is
sizeof(int)
the same on all computer systems? - How do you calculate the number of elements in an array using sizeof?
- Why might sizeof give unexpected results when used with function parameters?
Practice exercises
Try these sizeof exercises:
- Write a program that displays the sizes of all fundamental types on your system
- Create a function that calculates how much memory an array of N integers would use
- Compare the memory usage of storing 1000 boolean values as
bool
vsint
- Write a program that determines which integer type (
short
,int
,long
,long long
) is most appropriate for storing a given range of values
Explore More Courses
Discover other available courses while this lesson is being prepared.
Browse CoursesLesson Discussion
Share your thoughts and questions