In C++, both pointers and iterators are used to access and traverse data. They share several similarities, such as supporting dereferencing and increment operations, but they serve different purposes. Pointers directly manipulate memory addresses, whereas iterators provide a generalized way to traverse elements in containers.
- Pointers provide direct access to memory locations.
- Iterators provide a container-independent mechanism to access and traverse elements.
Pointer
A pointer is a variable is a variable that stores the memory address of another object.
- Provides direct access to memory locations.
- Commonly used for arrays, dynamic memory allocation, and low-level programming.
Example: The below example demonstrates the use of pointers to store the address of a variable.
// The output of this program can be differen in different runs.
#include <iostream>;
using namespace std;
int main()
{
int x=5;
int* myptr = &x;
cout << "Value of x is: " << x << endl;
cout << "address of x is: " << myptr << endl;
return 0;
}
Output
Value of x is: 5 address of x is: 0x7ffde9197ed4
Explanation: The pointer ptr stores the address of the variable x. Dereferencing the pointer using *ptr gives access to the value stored at that memory location.
Iterator
An iterator is an object used to access and traverse elements stored in STL containers.
- Provides a generic way to traverse different container types.
- Works seamlessly with STL algorithms and container operations.
Example: The below example demonstrates the use of iterators.
// C++ program to demonstrate iterators
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// Declaring a vector
vector<int> v = { 1, 2, 3 };
// Declaring an iterator
vector<int>::iterator i;
int j;
cout << "Without iterators = ";
// Accessing the elements without using iterators
for (j = 0; j < 3; ++j) {
cout << v[j] << " ";
}
cout << "\nWith iterators = ";
// Accessing the elements using iterators
for (i = v.begin(); i != v.end(); ++i) {
cout << *i << " ";
}
// Adding one more element to vector
v.push_back(4);
cout << "\nWithout iterators = ";
// Accessing the elements without using iterators
for (j = 0; j < 4; ++j) {
cout << v[j] << " ";
}
cout << "\nWith iterators = ";
// Accessing the elements using iterators
for (i = v.begin(); i != v.end(); ++i) {
cout << *i << " ";
}
return 0;
}
Output
Without iterators = 1 2 3 With iterators = 1 2 3 Without iterators = 1 2 3 4 With iterators = 1 2 3 4
Explanation: The program demonstrates traversing a vector both with array indexing and with iterators. After inserting a new element using push_back(), both methods are used again to access the updated contents of the vector.
Difference between Iterators and Pointers
Although iterators and pointers support similar operations such as dereferencing and incrementing, they differ in functionality and usage.
| Feature | Pointers | Iterators |
|---|---|---|
| Definition | Store the memory address of another object | Provide an abstraction for traversing container elements |
| Memory Access | Directly access memory locations | Access elements through container interfaces |
| Flexibility | Work with raw memory and arrays | Work with STL containers |
| Arithmetic Operations | Support pointer arithmetic (+, -, ++, --) | Supported only by specific iterator categories |
| Type Restrictions | Can point to any object of a compatible type | Usually restricted to elements of a particular container |
| Memory Management | Can be deleted using delete | Cannot be deleted directly |
| Safety | Prone to invalid memory access | Safer because container manages memory |
| Usage | Used in low-level programming and dynamic memory management | Used for container traversal and STL algorithms |
| Performance | Usually faster due to direct memory access | May introduce slight abstraction overhead |
Advantages of Iterators over Pointers
Iterators provide several advantages when working with STL containers:
- Work with different container types through a common interface.
- Integrate seamlessly with STL algorithms such as sort(), find(), and count().
- Support different traversal capabilities through iterator categories.
- Hide implementation details of the underlying container.