Addresses and Memory Basics
How memory addresses work: bytes, layout, and how pointers reference locations.
In C++, data is stored in the computer’s memory. Each variable has its own address in memory. Understanding memory addresses is essential for learning advanced C++ features like pointers. In this article, you will learn about memory structure, the concept of addresses, and how variables are stored in memory.
1. What is Memory?
Memory (RAM) is the area where data and instructions are temporarily stored while a program is running. When the program ends, the data in memory is erased. The C++ compiler allocates space in memory for variables and assigns them addresses.
For example, in the code below, each variable has a unique address in memory:
#include <iostream>
using namespace std;
int main() {
int age = 25;
double pi = 3.14;
cout << "Address of age: " << &age << endl;
cout << "Address of pi: " << &pi << endl;
return 0;
}
Example output:
Address of age: 0x61ff0c
Address of pi: 0x61ff08
Each address represents a physical location in memory and is typically displayed in **hexadecimal** format.
2. & (Address) Operator
The & operator returns the address of a variable —
that is, the memory location where its value is stored.
int number = 100;
cout << "Address of number: " << &number << endl;
cout << "Value of number: " << number << endl;
The address is a location, while the value is the data stored at that location. Understanding this distinction is key to grasping pointers.
3. Memory Structure (Stack and Heap)
When a C++ program runs, memory is generally divided into two main areas:
| Region | Description | Usage |
|---|---|---|
| Stack | Holds automatic (local) variables. Space is allocated when a function is called and released when it ends. | Automatic lifetime variables (int, double, etc.) |
| Heap | Used for dynamically allocated memory. Managed manually with new and delete. |
Dynamic data structures (objects created with new) |
Example:
int x = 10; // Stored on the stack
int *p = new int(5); // Stored on the heap
The pointer p itself is on the stack, but the value it points to is on the heap.
This distinction is important for avoiding memory leaks.
4. sizeof Operator
The sizeof operator returns the amount of memory (in bytes) that a variable or data type occupies.
#include <iostream>
using namespace std;
int main() {
cout << "Size of int: " << sizeof(int) << " bytes" << endl;
cout << "Size of double: " << sizeof(double) << " bytes" << endl;
cout << "Size of char: " << sizeof(char) << " bytes" << endl;
return 0;
}
Typical output on most systems:
int→ 4 bytesdouble→ 8 byteschar→ 1 byte
5. Visualizing Variables in Memory
Consider the following example:
int a = 5;
int b = 10;
Memory representation:
Address Value
0x61ff0c → 5 (a)
0x61ff08 → 10 (b)
Each variable has a distinct address. These addresses may increase or decrease depending on memory layout.
6. Introduction to Pointers
A pointer is a special variable that stores the address of another variable.
The * (asterisk) symbol is used to declare pointers.
#include <iostream>
using namespace std;
int main() {
int number = 42;
int *ptr = &number; // Assign the address of number to ptr
cout << "Value of number: " << number << endl;
cout << "Value pointed to by ptr: " << *ptr << endl;
cout << "Address stored in ptr: " << ptr << endl;
return 0;
}
&→ address operator (gets a variable’s address)*→ dereference operator (accesses the value stored at the address)
In this example, ptr holds the address of number.
Using *ptr accesses the value stored at that address.
7. Null Pointer and Safe Usage
Pointers should not point to invalid memory.
If a pointer doesn’t reference any address yet, it should be initialized with nullptr.
int *p = nullptr;
if (p == nullptr) {
cout << "The pointer is not pointing to any address." << endl;
}
This check helps prevent runtime errors and segmentation faults.
8. Pointer and Memory Diagram
Let’s look at the following example:
int x = 10;
int *p = &x;
Memory visualization:
Variable | Address | Value
x | 0x61ff0c | 10
p | 0x61ff08 | 0x61ff0c
The pointer p stores the address of x.
You can access x’s value by using *p.
9. Memory Management and Safety
In C++, direct memory management offers great power but also responsibility. Any dynamically allocated memory must be released with delete.
int *p = new int(100); // Allocate memory on the heap
cout << *p << endl;
delete p; // Free the memory
p = nullptr; // Prevent dangling pointer
A memory leak occurs when memory is not released properly,
which can slow down a program over time. Always pair each new with a delete.
10. TL;DR
- Each variable has an address in memory (use
&to obtain it). - Stack → automatic memory; Heap → dynamic memory.
sizeofshows how much space a type occupies.int *pdeclares a pointer;*paccesses the value.nullptrshould be used as a safe initial value.- Memory allocated with
newmust be released withdelete. - All examples can be executed in Visual Studio 2022 or GCC 11+.