SlideShare a Scribd company logo
Pointers & References
Ilio Catallo - info@iliocatallo.it
Outline
• The swap func*on
• Memory & addresses
• Pointers
• References
• Bibliography
The swap func)on
Swapping integers
Assume that we are wri-ng a program in which we o3en need to
swap two integers
┌──────────────────┐
│ │
│ ▼
┌───┐ ┌───┐
a:│ 2 │int b:│ 5 │int
└───┘ └───┘
▲ │
│ │
└──────────────────┘
Idea: wri%ng a swap_int func%on
Invoking swap_int
int main() {
int a = 2;
int b = 5;
// expected result: a = 5, b = 2
swap_int(a, b);
}
How to write the swap_int func.on?
First a(empt
void swap_int(int x, int y) {
int temp = x;
x = y;
y = temp;
}
First a(empt
At swap_int invoca*on:
• The values in a and b get copied into the local variables x and y
• The values in x and y get swapped, but...
• The values in a and b remain untouched
First a(empt
void swap_int(int x, int y) {
...
}
int main() {
int a = 2, b = 5;
swap_int(a, b); // x and y are copies of a and b
// hence, a and b remain unchanged
}
The swap problem
We conclude that it is not possible to write the swap_int
func1on if we pass parameters by value
Memory & addresses
Memory
During the execu-on of a program, data are stored in memory
Memory model
In C++, memory is modeled as a sequence of memory cells, where
each cell is of size 1 byte
┌──────┬──────┬──────┬──────┐
... │ │ │ │ │ ...
└──────┴──────┴──────┴──────┘
◀─────▶
1 byte
Memory model
Each memory cell is associated with a unique memory address
┌──────┬──────┬──────┬──────┐
... │ │ │ │ │ ...
└──────┴──────┴──────┴──────┘
0x7345
Memory model
Memory addresses are nothing more than numbers1
┌──────┬──────┬──────┬──────┐
... │ │ │ │ │ ...
└──────┴──────┴──────┴──────┘
0x7345
1
The 0x prefix is to say that the numbers are given in hexadecimal nota6on
Memory model
Given a cell, its address is obtained as the address of the previous
one plus one
┌──────┬──────┬──────┬──────┐
... │ │ │ │ │ ...
└──────┴──────┴──────┴──────┘
0x7345 0x7346 0x7347
Memory model
This assures that:
• Every memory cell has its own unique address
• Given a cell, it is possible to compute the address of its
neighborhood
Variable iden+fiers
We usually do not care about where values are stored
int a
◀───────────▶
┌──────┬──────┬──────┬──────┐
... │//////│//////│ │ │ ...
└──────┴──────┴──────┴──────┘
0x7345 0x7346 0x7347
Variable iden+fiers
We simply manipulate values by referring to the iden%fier of the
corresponding variable
int a = 3;
a = a + 7; // we do not know where `a` is stored in memory
Addresses
However, there might be situa2ons in which we would like to refer
to the in-memory loca-on of a value, rather than to the value itself
The ampersand
In order to manipulate the address of a variable, we prefix the
variable iden8fier with the ampersand symbol &
The ampersand
int a = 5;
std::cout << "value of a: " << a
<< std::endl;
std::cout << "address of a: " << &a
<< std::endl;
The address-of operator
When the ampersand symbol & precedes an expression2
, it plays
the role of a unary operator (the address-of operator)
int a = 7;
std::cout << &a; // conceptually: address_of(a);
2
Note that there exist expressions on which it is not possible to apply the address-of operator
The address-of operator
Note that if a value occupies more than one memory cell, the
address-of operator returns the address of the first memory cell
int a
◀───────────▶
┌──────┬──────┬──────┬──────┐
... │//////│//////│ │ │ ...
└──────┴──────┴──────┴──────┘
0x7345 0x7346 0x7347
▲
│
│
&a
A formal defini.on of copy
A copy is a something that is equal to the original but not iden)cal
to it
int a = 7;
int b = a;
a == b; // b is equal to a (they both contain 7)
&a != &b; // b is not a (they live in different memory locations)
Pointers
Storing addresses
Assume that we now want to store the address of a value. We need
a variable where to keep such an address
Storing addresses
int a = 7;
??? address_of_a = &a
What is the type of address_of_a?
Pointer to int
The data type of a variable storing the address of an int is int*.
Such a data type is called pointer to int
int* address_of_a = &a
Pointers
Variables that store addresses are called pointers
It is possible to create pointers to any data type3
, for built-in and
user-defined types alike
3
As long as the data type is at least of size 1 byte
For any data type T, T* is the data type pointer to T
Examples
int* a; // pointer to int
char* b; // pointer to char
float* c; // pointer to float
int** d; // pointer to pointer to int
XKCD
Pointers as type constructors
The * symbol plays the role of a type constructor
A type constructor is a func0on that takes as input some type T
and returns some other type T'
Example
Construc)ng the type "pointer to int"
• Input type: int
• Type constructor: *
• Output type: int*
vector as type constructor
No#ce that also std::vector is a type constructor
vector as type constructor
Indeed, no value can have a type of just std::vector, because
that is not a type per se
Example
Construc)ng the type "vector of double's"
• Input type: double
• Type constructor: std::vector
• Output type: std::vector<double>
Type constructors: a metaphor
Type constructors are like ♭ and ♯ in music
Type constructors: a metaphor
You cannot play ♭ or ♯ alone
Type constructors: a metaphor
You rather apply ♭ or ♯ to a note to obtain a new one
Type constructors: a metaphor
Construc)ng the note A♭
• Input note: A
• Note constructor: ♭
• Output note: A♭
Using pointers
Using pointers
Assume we are storing the address of an integer variable in a
pointer
int* ptr = ... // somehow initialized
What opera*ons can I do on pointers?
Dereferencing
The dereference operator * makes possible to access the content
pointed to by a pointer4
int* ptr = ...
std::cout << "the value pointed to is: " << *ptr;
4
The dereference operator is also called the indirec'on operator
Dereferencing
The expression *ptr reads "the value pointed to by ptr"
int* ptr = ...
std::cout << "the value pointed to is: " << *ptr;
Dereferencing
The dereference operator allows both reading and modifying the
pointed value
int* ptr = ...
*ptr = 7;
int b = 5 + *ptr; // b contains 12
Dereferencing
In other words, the expression *ptr may also appear on the le4-
hand side of the assignment operator
int* ptr = ...
*ptr = 7;
int b = 5 + *ptr; // b contains 12
Same symbol, two meanings
// * is a type constructor
int* ptr_a = &a;
// * is an operator
std::cout << "pointed value: " << *ptr_a;
Trivia 1: What's the output?
int a = 7;
int* ptr = &a;
*ptr = 12;
std::cout << *ptr << std::endl;
std::cout << a << std::endl;
Trivia 2: What's the output?
int a = 7;
int* ptr = &a;
std::cout << &ptr << std::endl;
std::cout << &a << std::endl;
Trivia 3: What's the output?
int a = 7;
int* ptr1 = &a;
int* ptr2 = &a;
std::cout << (ptr1 == ptr2) << std::endl;
std::cout << (&ptr1 == &ptr2) << std::endl;
The "box" metaphor
The "box" metaphor
Just as a vector is a container of many elements, we can say that a
pointer is a container of one element5
5
More formally, the similarity holds because both of them are functors
The "box" metaphor
// we put some values in the container
std::vector<int> v = {1, 2, 3, 4, 5};
// accessing the 3rd element
// in the container
std::cout << v[2];
The "box" metaphor
// we "put" a value in the container
int* p = &a;
// accessing the only element
// in the container
std::cout << *p;
Geek and Poke
The strange case of null pointers
Unini$alized pointers
As with any local variable, it is not possible to foresee the value of
unini6alized pointers
int* ptr; // uninitialized pointer
Unini$alized pointers
The pointer may hold any value. Such a value will be erroneously
intended as the address of a pointed value
int* ptr; // uninitialized pointer
Unini$alized pointers
There does not exist any way to understand whether a pointer is in
fact poin4ng to a valid value
int* ptr; // uninitialized pointer
Null pointers
We would like to ini#alize pointers even in the absence of a
sensible value
int* ptr = ???;
Null pointers
Pointers can be ini-alized to null in order to indicate that the
pointer is currently not poin-ng to any valid value6
int* ptr = nullptr; // since C++11
int* ptr = NULL; // C++03
6
In terms of the box metaphor, this amounts to no4fying that the container is empty
Solving the swap problem
Can we use pointers to write a working version of the swap_int
func4on?
Idea: passing to swap_int the variable addresses (as
opposed to their values)
swap_int with pointers
void swap_int(??? x, ??? y) {
...
}
swap_int with pointers
void swap_int(int* x, int* y) {
...
}
swap_int with pointers
void swap_int(int* x, int* y) {
int temp = *x;
*x = *y;
*y = temp;
}
swap_int with pointers
At swap_int invoca*on:
• The addresses of a and b get copied into the pointers x and y
(which are local to swap_int)
• The values pointed to by x and y (i.e., a and b) get swapped
• At the end of swap_int, x and y get destroyed
How to invoke swap_int?
int main() {
int a = 2;
int b = 5;
swap_int(???, ???);
}
How to invoke swap_int?
int main() {
int a = 2;
int b = 5;
swap_int(&a, &b);
}
Passing by address
If a func(on receives addresses in place of values, we say that
parameter are passed by address
void swap_int(int* x, int* y);
Passing by address
However, since we pass address copies, passing by address is just a
par6cular case of passing by value
void swap_int(int* x, int* y);
Passing by address
Passing by address allows...
• propaga'ng altera'ons in the callee func'on also in the calling
func'on
• rapidly accessing big data, since we copy its address as opposed
to its value
Passing by address
However:
• The code is difficult to read
• We should manage the edge case where we pass nullptr
Passing by address
Upsides/downsides:
• We cannot pass constants or temporary data (they do not have
an address)
References
Iden%fiers
When declaring a variable, we need to specify its data type and
iden*fier
Both these aspects cannot be modified later on in the program
Iden%fier aliases
However, C++ allows introducing addi5onal iden5fiers (aliases) for
a variables any5me in the code
int a = 5;
int& b = a; // b is a new identifier (alias) for a
Iden%fier aliases
b is an alias for a, and its data type is int&
int a = 5;
int& b = a; // b is a new identifier (alias) for a
References
In C++, iden*fier aliases are called references7
int a = 5;
int& b = a; // b is a reference to a
7
Star'ng from C++11, references have been renamed lvalue references
For a data type T, T& is the data type reference to T
Examples
int& a = b; // a is an alias for b (where b is of type int)
float& c = d // c is an alias for d (where d is of type float)
int& e = b; // e is an alias for b, hence an alias for a
int*& f = g; // f is an alias for g (where g is of type int*)
Trivia 1: what's the output?
int a = 5;
int& b = a;
b = 7;
std::cout << a;
Trivia 1: what's the output?
int a = 5;
int& b = a; // b is a new name for a
b = 7;
std::cout << a; // the output will be 7
Aliases are indis+nguishable
Once ini'alized, using either the new or the old iden'fier is a
ma7er of indifference
int a = 5;
int& b = a; // b is a new name for a
// using b is the same as using a (and vice-versa)
std::cout << b;
Aliases are indis+nguishable
That is, the reference is the referent8
int a = 5;
int& b = a; // b is a new name for a
// using b is the same as using a (and vice-versa)
std::cout << b;
8
While holding conceptually, the C++11 specifica8on qualifies the reference and the referent as two different
en88es
& as a type constructor
As with *, also & can be intended as a type constructor
& as a type constructor
Construc)ng the type "reference to float"
• Input type: float
• Type constructor: &
• Output type: float&
Same symbol, two meanings
int a = 5;
// & is a type constructor
int& b = a;
// & is an operator
std::cout << &a;
Solving the swap problem
Can we use references to write a working version of the swap_int
func3on?
Idea: using references as parameters of swap_int
swap_int with references
void swap_int(??? x, ??? y) {
...
}
swap_int with references
void swap_int(int& x, int& y) {
...
}
swap_int with references
void swap_int(int& x, int& y) {
int temp = x;
x = y;
y = temp;
}
swap_int with references
Note that the func,on body is the same as in our first a5empt
void swap_int(int& x, int& y) {
int temp = x;
x = y;
y = temp;
}
How to invoke swap_int?
int main() {
int a = 2;
int b = 5;
swap_int(???, ???);
}
How to invoke swap_int?
int main() {
int a = 2;
int b = 5;
swap_int(a, b);
}
How to invoke swap_int?
Note that we invoke swap_int as any other func3on
int main() {
int a = 2;
int b = 5;
swap_int(a, b);
}
swap_int with references
References allow us to write swap_int in an easy and safe
manner
• Easy: we do not need to use the dereference operator *
everywhere
• Safe: the program will not compile if we try to pass nullptr or
temporary values
Passing by reference
If a func(on receives iden%fier aliases in place of values, we say
that parameter are passed by reference
void swap_int(int& x, int& y);
Gotchas with references
Does it work?
int a = 5;
int& b;
b = a;
References are not assignable
References can be ini#alized, but not (re)-assigned
int a = 5;
int& b; // b is an alias for what?
b = a;
Does it work?
void countdown(int& number) {
std::cout << number << std::endl;
if (number != 0)
countdown(number - 1);
}
The compile-,me error
Here's the error:
error: invalid initialization of non-const reference of
type 'int&' from an rvalue of type 'int'
The compile-,me error
We can safely replace the term rvalue with temporary:
error: invalid initialization of non-const reference of
type 'int&' from a temporary of type 'int'
The compile-,me error
The temporary the error is referring to is number - 1
void countdown(int& number) {
std::cout << number << std::endl;
if (number != 0)
countdown(number - 1);
}
Reference-to-const
The correct version reads:
void countdown(int const& number) {
std::cout << number << std::endl;
if (number != 0)
countdown(number - 1);
}
Reference-to-const
Only constant references can bind to temporary values
void countdown(int const& number) {
std::cout << number << std::endl;
if (number != 0)
countdown(number - 1);
}
Reference-to-const
This is why the input parameter number has to be of type int
const&, rather than int&
void countdown(int const& number) {
std::cout << number << std::endl;
if (number != 0)
countdown(number - 1);
}
Does it work?
double& add(double x, double y) {
double z = x + y;
return z;
}
Dangling references
Although it compiles, the add func2on causes an undefined
behavior
double& add(double x, double y) {
double z = x + y;
return z;
}
Dangling references
This is because we are returning an alias for z, which will be
destroyed as soon as we exit the func7on
double& add(double x, double y) {
double z = x + y;
return z;
}
Dangling references
In other words, the add func0on returns a dangling reference, that
is, a reference for a non-exis0ng object
double& add(double x, double y) {
double z = x + y;
return z;
}
int main() {
double r = add(5, 3);
std::cout << r;
}
Dangling references
Although this seems trivial when presented in contrived examples,
this is an easy mistake to make when wri9ng class' ge;ers and
se;ers
Bibliography
Bibliography
• S. B. Lippman, J. Lajoie, B. E. Moo, C++ Primer (5th Ed.)
• B. Stroustrup, The C++ Programming Language (4th Ed.)
• R. Lafore, Object Oriented Programming in C++ (4th Ed.)
• C++FAQ, SecJon 8

More Related Content

PPTX
Pointer in C
PPTX
Pointers in c - Mohammad Salman
PPTX
Function Pointer
PDF
Files and streams
PPTX
Pointer in C++
PPTX
Call by value or call by reference in C++
PPTX
Constructors and destructors
PPTX
Stream classes in C++
Pointer in C
Pointers in c - Mohammad Salman
Function Pointer
Files and streams
Pointer in C++
Call by value or call by reference in C++
Constructors and destructors
Stream classes in C++

What's hot (20)

PPTX
Computer Science:Pointers in C
PDF
VIT351 Software Development VI Unit3
PPT
Introduction to pointers and memory management in C
PPT
Functions in C++
PPTX
Array Of Pointers
PPTX
Pointer in c program
PDF
Pointers
PPTX
Pointers in c++
PPTX
Destructors
PPTX
Pointers in C Language
PDF
Constructor and Destructor
PPTX
Array in C
PPTX
Data members and member functions
PPTX
Storage classes in C
PPT
Pointers C programming
PPT
Memory allocation in c
PPT
Function overloading(c++)
ODP
Pointers in c++ by minal
PPTX
Inheritance in c++
PPTX
Pointers in c++
Computer Science:Pointers in C
VIT351 Software Development VI Unit3
Introduction to pointers and memory management in C
Functions in C++
Array Of Pointers
Pointer in c program
Pointers
Pointers in c++
Destructors
Pointers in C Language
Constructor and Destructor
Array in C
Data members and member functions
Storage classes in C
Pointers C programming
Memory allocation in c
Function overloading(c++)
Pointers in c++ by minal
Inheritance in c++
Pointers in c++
Ad

Viewers also liked (20)

DOCX
Pratik Bakane C++
PDF
Pointer in c++ part1
PPTX
Pointers in c++
PPTX
C++ Pointers
PPT
02 c++ Array Pointer
DOCX
Pratik Bakane C++
PDF
C++ programs
PPT
C++ Pointers And References
DOCX
Travel management
PPT
C++ programming
DOCX
Pratik Bakane C++
DOCX
Pratik Bakane C++
PPTX
Алексей Кутумов, Вектор с нуля
PPTX
intro to pointer C++
PPTX
Learning C++ - Pointers in c++ 2
PDF
HexRaysCodeXplorer: object oriented RE for fun and profit
PPT
C++: inheritance, composition, polymorphism
PPT
Unit 6 pointers
PPT
Stl Containers
Pratik Bakane C++
Pointer in c++ part1
Pointers in c++
C++ Pointers
02 c++ Array Pointer
Pratik Bakane C++
C++ programs
C++ Pointers And References
Travel management
C++ programming
Pratik Bakane C++
Pratik Bakane C++
Алексей Кутумов, Вектор с нуля
intro to pointer C++
Learning C++ - Pointers in c++ 2
HexRaysCodeXplorer: object oriented RE for fun and profit
C++: inheritance, composition, polymorphism
Unit 6 pointers
Stl Containers
Ad

Similar to Pointers & References in C++ (20)

PPTX
Computer Programming Lecture numer 05 -- pointers,variablesb
PPTX
Intro To C++ - Class #17: Pointers!, Objects Talking To Each Other
PPT
Pointer
PDF
(4) cpp automatic arrays_pointers_c-strings
PDF
Chapter 2 - Introduction to Pointer Variables - Student.pdf
PDF
Pointers andmemory
PPT
Lecture2.ppt
DOCX
Case study how pointer plays very important role in data structure
PPT
Bsc cs 1 pic u-5 pointer, structure ,union and intro to file handling
PPT
Diploma ii cfpc- u-5.1 pointer, structure ,union and intro to file handling
PDF
Chapter 5 (Part I) - Pointers.pdf
PPT
pointer, structure ,union and intro to file handling
PPT
Btech 1 pic u-5 pointer, structure ,union and intro to file handling
PPT
pointer, structure ,union and intro to file handling
PPTX
Chp3(pointers ref)
PDF
C Pointers
PPT
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
PPTX
Introduction to pointers in c plus plus .
PPTX
Pointers in C++ object oriented programming
PPTX
Object Oriented Programming using C++: Ch10 Pointers.pptx
Computer Programming Lecture numer 05 -- pointers,variablesb
Intro To C++ - Class #17: Pointers!, Objects Talking To Each Other
Pointer
(4) cpp automatic arrays_pointers_c-strings
Chapter 2 - Introduction to Pointer Variables - Student.pdf
Pointers andmemory
Lecture2.ppt
Case study how pointer plays very important role in data structure
Bsc cs 1 pic u-5 pointer, structure ,union and intro to file handling
Diploma ii cfpc- u-5.1 pointer, structure ,union and intro to file handling
Chapter 5 (Part I) - Pointers.pdf
pointer, structure ,union and intro to file handling
Btech 1 pic u-5 pointer, structure ,union and intro to file handling
pointer, structure ,union and intro to file handling
Chp3(pointers ref)
C Pointers
Mca 1 pic u-5 pointer, structure ,union and intro to file handling
Introduction to pointers in c plus plus .
Pointers in C++ object oriented programming
Object Oriented Programming using C++: Ch10 Pointers.pptx

More from Ilio Catallo (20)

PDF
C++ Standard Template Library
PDF
Regular types in C++
PDF
Resource wrappers in C++
PDF
Memory management in C++
PDF
Operator overloading in C++
PDF
Multidimensional arrays in C++
PDF
Arrays in C++
PDF
Spring MVC - Wiring the different layers
PDF
Java and Java platforms
PDF
Spring MVC - Web Forms
PDF
Spring MVC - The Basics
PDF
Web application architecture
PDF
Introduction To Spring
PDF
Gestione della memoria in C++
PDF
Array in C++
PDF
Puntatori e Riferimenti
PDF
Java Persistence API
PDF
JSP Standard Tag Library
PDF
Internationalization in Jakarta Struts 1.3
PDF
Validation in Jakarta Struts 1.3
C++ Standard Template Library
Regular types in C++
Resource wrappers in C++
Memory management in C++
Operator overloading in C++
Multidimensional arrays in C++
Arrays in C++
Spring MVC - Wiring the different layers
Java and Java platforms
Spring MVC - Web Forms
Spring MVC - The Basics
Web application architecture
Introduction To Spring
Gestione della memoria in C++
Array in C++
Puntatori e Riferimenti
Java Persistence API
JSP Standard Tag Library
Internationalization in Jakarta Struts 1.3
Validation in Jakarta Struts 1.3

Recently uploaded (20)

PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPTX
Spectroscopy.pptx food analysis technology
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Encapsulation theory and applications.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Approach and Philosophy of On baking technology
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Electronic commerce courselecture one. Pdf
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Machine learning based COVID-19 study performance prediction
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
Dropbox Q2 2025 Financial Results & Investor Presentation
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Spectroscopy.pptx food analysis technology
Chapter 3 Spatial Domain Image Processing.pdf
Encapsulation theory and applications.pdf
The AUB Centre for AI in Media Proposal.docx
Approach and Philosophy of On baking technology
Reach Out and Touch Someone: Haptics and Empathic Computing
Mobile App Security Testing_ A Comprehensive Guide.pdf
Electronic commerce courselecture one. Pdf
MYSQL Presentation for SQL database connectivity
20250228 LYD VKU AI Blended-Learning.pptx
Machine learning based COVID-19 study performance prediction
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Spectral efficient network and resource selection model in 5G networks
Building Integrated photovoltaic BIPV_UPV.pdf

Pointers & References in C++

  • 1. Pointers & References Ilio Catallo - info@iliocatallo.it
  • 2. Outline • The swap func*on • Memory & addresses • Pointers • References • Bibliography
  • 4. Swapping integers Assume that we are wri-ng a program in which we o3en need to swap two integers ┌──────────────────┐ │ │ │ ▼ ┌───┐ ┌───┐ a:│ 2 │int b:│ 5 │int └───┘ └───┘ ▲ │ │ │ └──────────────────┘
  • 5. Idea: wri%ng a swap_int func%on
  • 6. Invoking swap_int int main() { int a = 2; int b = 5; // expected result: a = 5, b = 2 swap_int(a, b); }
  • 7. How to write the swap_int func.on?
  • 8. First a(empt void swap_int(int x, int y) { int temp = x; x = y; y = temp; }
  • 9. First a(empt At swap_int invoca*on: • The values in a and b get copied into the local variables x and y • The values in x and y get swapped, but... • The values in a and b remain untouched
  • 10. First a(empt void swap_int(int x, int y) { ... } int main() { int a = 2, b = 5; swap_int(a, b); // x and y are copies of a and b // hence, a and b remain unchanged }
  • 11. The swap problem We conclude that it is not possible to write the swap_int func1on if we pass parameters by value
  • 13. Memory During the execu-on of a program, data are stored in memory
  • 14. Memory model In C++, memory is modeled as a sequence of memory cells, where each cell is of size 1 byte ┌──────┬──────┬──────┬──────┐ ... │ │ │ │ │ ... └──────┴──────┴──────┴──────┘ ◀─────▶ 1 byte
  • 15. Memory model Each memory cell is associated with a unique memory address ┌──────┬──────┬──────┬──────┐ ... │ │ │ │ │ ... └──────┴──────┴──────┴──────┘ 0x7345
  • 16. Memory model Memory addresses are nothing more than numbers1 ┌──────┬──────┬──────┬──────┐ ... │ │ │ │ │ ... └──────┴──────┴──────┴──────┘ 0x7345 1 The 0x prefix is to say that the numbers are given in hexadecimal nota6on
  • 17. Memory model Given a cell, its address is obtained as the address of the previous one plus one ┌──────┬──────┬──────┬──────┐ ... │ │ │ │ │ ... └──────┴──────┴──────┴──────┘ 0x7345 0x7346 0x7347
  • 18. Memory model This assures that: • Every memory cell has its own unique address • Given a cell, it is possible to compute the address of its neighborhood
  • 19. Variable iden+fiers We usually do not care about where values are stored int a ◀───────────▶ ┌──────┬──────┬──────┬──────┐ ... │//////│//////│ │ │ ... └──────┴──────┴──────┴──────┘ 0x7345 0x7346 0x7347
  • 20. Variable iden+fiers We simply manipulate values by referring to the iden%fier of the corresponding variable int a = 3; a = a + 7; // we do not know where `a` is stored in memory
  • 21. Addresses However, there might be situa2ons in which we would like to refer to the in-memory loca-on of a value, rather than to the value itself
  • 22. The ampersand In order to manipulate the address of a variable, we prefix the variable iden8fier with the ampersand symbol &
  • 23. The ampersand int a = 5; std::cout << "value of a: " << a << std::endl; std::cout << "address of a: " << &a << std::endl;
  • 24. The address-of operator When the ampersand symbol & precedes an expression2 , it plays the role of a unary operator (the address-of operator) int a = 7; std::cout << &a; // conceptually: address_of(a); 2 Note that there exist expressions on which it is not possible to apply the address-of operator
  • 25. The address-of operator Note that if a value occupies more than one memory cell, the address-of operator returns the address of the first memory cell int a ◀───────────▶ ┌──────┬──────┬──────┬──────┐ ... │//////│//////│ │ │ ... └──────┴──────┴──────┴──────┘ 0x7345 0x7346 0x7347 ▲ │ │ &a
  • 26. A formal defini.on of copy A copy is a something that is equal to the original but not iden)cal to it int a = 7; int b = a; a == b; // b is equal to a (they both contain 7) &a != &b; // b is not a (they live in different memory locations)
  • 28. Storing addresses Assume that we now want to store the address of a value. We need a variable where to keep such an address
  • 29. Storing addresses int a = 7; ??? address_of_a = &a
  • 30. What is the type of address_of_a?
  • 31. Pointer to int The data type of a variable storing the address of an int is int*. Such a data type is called pointer to int int* address_of_a = &a
  • 32. Pointers Variables that store addresses are called pointers It is possible to create pointers to any data type3 , for built-in and user-defined types alike 3 As long as the data type is at least of size 1 byte
  • 33. For any data type T, T* is the data type pointer to T
  • 34. Examples int* a; // pointer to int char* b; // pointer to char float* c; // pointer to float int** d; // pointer to pointer to int
  • 35. XKCD
  • 36. Pointers as type constructors The * symbol plays the role of a type constructor A type constructor is a func0on that takes as input some type T and returns some other type T'
  • 37. Example Construc)ng the type "pointer to int" • Input type: int • Type constructor: * • Output type: int*
  • 38. vector as type constructor No#ce that also std::vector is a type constructor
  • 39. vector as type constructor Indeed, no value can have a type of just std::vector, because that is not a type per se
  • 40. Example Construc)ng the type "vector of double's" • Input type: double • Type constructor: std::vector • Output type: std::vector<double>
  • 41. Type constructors: a metaphor Type constructors are like ♭ and ♯ in music
  • 42. Type constructors: a metaphor You cannot play ♭ or ♯ alone
  • 43. Type constructors: a metaphor You rather apply ♭ or ♯ to a note to obtain a new one
  • 44. Type constructors: a metaphor Construc)ng the note A♭ • Input note: A • Note constructor: ♭ • Output note: A♭
  • 46. Using pointers Assume we are storing the address of an integer variable in a pointer int* ptr = ... // somehow initialized
  • 47. What opera*ons can I do on pointers?
  • 48. Dereferencing The dereference operator * makes possible to access the content pointed to by a pointer4 int* ptr = ... std::cout << "the value pointed to is: " << *ptr; 4 The dereference operator is also called the indirec'on operator
  • 49. Dereferencing The expression *ptr reads "the value pointed to by ptr" int* ptr = ... std::cout << "the value pointed to is: " << *ptr;
  • 50. Dereferencing The dereference operator allows both reading and modifying the pointed value int* ptr = ... *ptr = 7; int b = 5 + *ptr; // b contains 12
  • 51. Dereferencing In other words, the expression *ptr may also appear on the le4- hand side of the assignment operator int* ptr = ... *ptr = 7; int b = 5 + *ptr; // b contains 12
  • 52. Same symbol, two meanings // * is a type constructor int* ptr_a = &a; // * is an operator std::cout << "pointed value: " << *ptr_a;
  • 53. Trivia 1: What's the output? int a = 7; int* ptr = &a; *ptr = 12; std::cout << *ptr << std::endl; std::cout << a << std::endl;
  • 54. Trivia 2: What's the output? int a = 7; int* ptr = &a; std::cout << &ptr << std::endl; std::cout << &a << std::endl;
  • 55. Trivia 3: What's the output? int a = 7; int* ptr1 = &a; int* ptr2 = &a; std::cout << (ptr1 == ptr2) << std::endl; std::cout << (&ptr1 == &ptr2) << std::endl;
  • 57. The "box" metaphor Just as a vector is a container of many elements, we can say that a pointer is a container of one element5 5 More formally, the similarity holds because both of them are functors
  • 58. The "box" metaphor // we put some values in the container std::vector<int> v = {1, 2, 3, 4, 5}; // accessing the 3rd element // in the container std::cout << v[2];
  • 59. The "box" metaphor // we "put" a value in the container int* p = &a; // accessing the only element // in the container std::cout << *p;
  • 61. The strange case of null pointers
  • 62. Unini$alized pointers As with any local variable, it is not possible to foresee the value of unini6alized pointers int* ptr; // uninitialized pointer
  • 63. Unini$alized pointers The pointer may hold any value. Such a value will be erroneously intended as the address of a pointed value int* ptr; // uninitialized pointer
  • 64. Unini$alized pointers There does not exist any way to understand whether a pointer is in fact poin4ng to a valid value int* ptr; // uninitialized pointer
  • 65. Null pointers We would like to ini#alize pointers even in the absence of a sensible value int* ptr = ???;
  • 66. Null pointers Pointers can be ini-alized to null in order to indicate that the pointer is currently not poin-ng to any valid value6 int* ptr = nullptr; // since C++11 int* ptr = NULL; // C++03 6 In terms of the box metaphor, this amounts to no4fying that the container is empty
  • 67. Solving the swap problem Can we use pointers to write a working version of the swap_int func4on?
  • 68. Idea: passing to swap_int the variable addresses (as opposed to their values)
  • 69. swap_int with pointers void swap_int(??? x, ??? y) { ... }
  • 70. swap_int with pointers void swap_int(int* x, int* y) { ... }
  • 71. swap_int with pointers void swap_int(int* x, int* y) { int temp = *x; *x = *y; *y = temp; }
  • 72. swap_int with pointers At swap_int invoca*on: • The addresses of a and b get copied into the pointers x and y (which are local to swap_int) • The values pointed to by x and y (i.e., a and b) get swapped • At the end of swap_int, x and y get destroyed
  • 73. How to invoke swap_int? int main() { int a = 2; int b = 5; swap_int(???, ???); }
  • 74. How to invoke swap_int? int main() { int a = 2; int b = 5; swap_int(&a, &b); }
  • 75. Passing by address If a func(on receives addresses in place of values, we say that parameter are passed by address void swap_int(int* x, int* y);
  • 76. Passing by address However, since we pass address copies, passing by address is just a par6cular case of passing by value void swap_int(int* x, int* y);
  • 77. Passing by address Passing by address allows... • propaga'ng altera'ons in the callee func'on also in the calling func'on • rapidly accessing big data, since we copy its address as opposed to its value
  • 78. Passing by address However: • The code is difficult to read • We should manage the edge case where we pass nullptr
  • 79. Passing by address Upsides/downsides: • We cannot pass constants or temporary data (they do not have an address)
  • 81. Iden%fiers When declaring a variable, we need to specify its data type and iden*fier Both these aspects cannot be modified later on in the program
  • 82. Iden%fier aliases However, C++ allows introducing addi5onal iden5fiers (aliases) for a variables any5me in the code int a = 5; int& b = a; // b is a new identifier (alias) for a
  • 83. Iden%fier aliases b is an alias for a, and its data type is int& int a = 5; int& b = a; // b is a new identifier (alias) for a
  • 84. References In C++, iden*fier aliases are called references7 int a = 5; int& b = a; // b is a reference to a 7 Star'ng from C++11, references have been renamed lvalue references
  • 85. For a data type T, T& is the data type reference to T
  • 86. Examples int& a = b; // a is an alias for b (where b is of type int) float& c = d // c is an alias for d (where d is of type float) int& e = b; // e is an alias for b, hence an alias for a int*& f = g; // f is an alias for g (where g is of type int*)
  • 87. Trivia 1: what's the output? int a = 5; int& b = a; b = 7; std::cout << a;
  • 88. Trivia 1: what's the output? int a = 5; int& b = a; // b is a new name for a b = 7; std::cout << a; // the output will be 7
  • 89. Aliases are indis+nguishable Once ini'alized, using either the new or the old iden'fier is a ma7er of indifference int a = 5; int& b = a; // b is a new name for a // using b is the same as using a (and vice-versa) std::cout << b;
  • 90. Aliases are indis+nguishable That is, the reference is the referent8 int a = 5; int& b = a; // b is a new name for a // using b is the same as using a (and vice-versa) std::cout << b; 8 While holding conceptually, the C++11 specifica8on qualifies the reference and the referent as two different en88es
  • 91. & as a type constructor As with *, also & can be intended as a type constructor
  • 92. & as a type constructor Construc)ng the type "reference to float" • Input type: float • Type constructor: & • Output type: float&
  • 93. Same symbol, two meanings int a = 5; // & is a type constructor int& b = a; // & is an operator std::cout << &a;
  • 94. Solving the swap problem Can we use references to write a working version of the swap_int func3on?
  • 95. Idea: using references as parameters of swap_int
  • 96. swap_int with references void swap_int(??? x, ??? y) { ... }
  • 97. swap_int with references void swap_int(int& x, int& y) { ... }
  • 98. swap_int with references void swap_int(int& x, int& y) { int temp = x; x = y; y = temp; }
  • 99. swap_int with references Note that the func,on body is the same as in our first a5empt void swap_int(int& x, int& y) { int temp = x; x = y; y = temp; }
  • 100. How to invoke swap_int? int main() { int a = 2; int b = 5; swap_int(???, ???); }
  • 101. How to invoke swap_int? int main() { int a = 2; int b = 5; swap_int(a, b); }
  • 102. How to invoke swap_int? Note that we invoke swap_int as any other func3on int main() { int a = 2; int b = 5; swap_int(a, b); }
  • 103. swap_int with references References allow us to write swap_int in an easy and safe manner • Easy: we do not need to use the dereference operator * everywhere • Safe: the program will not compile if we try to pass nullptr or temporary values
  • 104. Passing by reference If a func(on receives iden%fier aliases in place of values, we say that parameter are passed by reference void swap_int(int& x, int& y);
  • 106. Does it work? int a = 5; int& b; b = a;
  • 107. References are not assignable References can be ini#alized, but not (re)-assigned int a = 5; int& b; // b is an alias for what? b = a;
  • 108. Does it work? void countdown(int& number) { std::cout << number << std::endl; if (number != 0) countdown(number - 1); }
  • 109. The compile-,me error Here's the error: error: invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int'
  • 110. The compile-,me error We can safely replace the term rvalue with temporary: error: invalid initialization of non-const reference of type 'int&' from a temporary of type 'int'
  • 111. The compile-,me error The temporary the error is referring to is number - 1 void countdown(int& number) { std::cout << number << std::endl; if (number != 0) countdown(number - 1); }
  • 112. Reference-to-const The correct version reads: void countdown(int const& number) { std::cout << number << std::endl; if (number != 0) countdown(number - 1); }
  • 113. Reference-to-const Only constant references can bind to temporary values void countdown(int const& number) { std::cout << number << std::endl; if (number != 0) countdown(number - 1); }
  • 114. Reference-to-const This is why the input parameter number has to be of type int const&, rather than int& void countdown(int const& number) { std::cout << number << std::endl; if (number != 0) countdown(number - 1); }
  • 115. Does it work? double& add(double x, double y) { double z = x + y; return z; }
  • 116. Dangling references Although it compiles, the add func2on causes an undefined behavior double& add(double x, double y) { double z = x + y; return z; }
  • 117. Dangling references This is because we are returning an alias for z, which will be destroyed as soon as we exit the func7on double& add(double x, double y) { double z = x + y; return z; }
  • 118. Dangling references In other words, the add func0on returns a dangling reference, that is, a reference for a non-exis0ng object double& add(double x, double y) { double z = x + y; return z; } int main() { double r = add(5, 3); std::cout << r; }
  • 119. Dangling references Although this seems trivial when presented in contrived examples, this is an easy mistake to make when wri9ng class' ge;ers and se;ers
  • 121. Bibliography • S. B. Lippman, J. Lajoie, B. E. Moo, C++ Primer (5th Ed.) • B. Stroustrup, The C++ Programming Language (4th Ed.) • R. Lafore, Object Oriented Programming in C++ (4th Ed.) • C++FAQ, SecJon 8