0% found this document useful (0 votes)
36 views

Lecture Notes 03 (CSI2372 - Advanced Programming Concepts With C++)

C++ notes at the University of Ottawa

Uploaded by

Yosri Ketata
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views

Lecture Notes 03 (CSI2372 - Advanced Programming Concepts With C++)

C++ notes at the University of Ottawa

Uploaded by

Yosri Ketata
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

CSI2372 - Advanced Programming Concepts with C++

Instructor: Shahram Moradi


Contact: [email protected]
Office Hours: Tuesday 9:30 to 10:30 AM
Office: Room 344 ARC Building, 25 Templeton St., Ottawa, ON, Canada

Course Overview:
Advanced Programming Concepts with C++ (CSI2372) is designed to expand your programming skills and deepen your
understanding of C++ and its applications. Throughout the course, we will explore various advanced programming
concepts, ranging from differences between C++ and Java programming to numerical computation and interfacing with
hardware.

Teaching Assistant:
1. Bhattacharjee/Mayukh, email: [email protected]
2. Dai/Lansu, email: [email protected]
3. Emami Afshar/Bahar, email: [email protected]
4. Khare/Akshat, email: [email protected]
5. Kumar/Preyank, email: [email protected]
6. Yathirajulu/Ruchitha, email: [email protected]
7. Keswani /Yash, email: [email protected]

1
CSI2372 - Advanced Programming Concepts with C++
Course Outline:

Throughout this course, we will explore the following topics:


Module 1: Foundations of C++ Programming
• Session 1: Introduction and Contrasting C++ with Java Programming
• Session 2: C++ Data Types and Their Applications
• Session 3: Pointers, Memory Management, and Efficiency
❑ Midterm 1: Assessment covering Sessions 1-3
Module 2: Object-Oriented Paradigm and File Handling
• Session 4: Embracing Object-Oriented Programming in C++
• Session 5: Navigating File and Stream Input/Output in C++
• Session 6: Preprocessor Macros and Their Role
❑ Midterm 2: Assessment covering Sessions 4-6
Module 3: Templates, Computation, and Practical Applications
• Session 7: Harnessing Templates and the Standard Template Library
• Session 8: Numerical Computation Techniques using C++
• Session 9: Interface Integration with Hardware Components
• Session 10: Exploring Engineering Applications
❑ Final Exam: Comprehensive Assessment of All Modules

2
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
• Session 2: Pointers, Memory Management, and Efficiency
• Pointer Arithmetic and Advanced Data Structures
• Function Pointers and Callbacks
• Pointer to Pointers and Pointers to Functions
• Pointer Safety and Best Practices
• Low-Level Memory Access and Assembly

3
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency

Pointer Arithmetic and Advanced Data Structures:


Understanding pointer arithmetic.
Working with multidimensional arrays using pointers.
Advanced data structures like linked lists, trees, and graphs with pointers.
Function Pointers and Callbacks:
Exploring function pointers and their applications.
Using function pointers for callback mechanisms.
Implementing dynamic function dispatch with pointers.
Pointer to Pointers and Pointers to Functions:
Understanding double pointers and their uses.
Function pointers to handle arrays of functions.
Real-world examples of complex pointer-to-function scenarios.
Pointer Safety and Best Practices:
Strategies for avoiding common pointer errors (e.g., null pointer, dangling pointer).
Smart pointers in C++ and their role in memory management.
Memory safety with pointers in languages like Rust.

4
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Understanding pointer arithmetic.
❑ Pointer arithmetic is a fundamental concept in C and C++ that allows you to perform arithmetic
operations on pointers to navigate and manipulate memory. It's an essential skill for low-level
programming, data manipulation, and working with arrays and data structures. Pointer arithmetic is
closely related to the size of the data type being pointed to.

int numbers[] = {10, 20, 30, 40, 50};


//Create an array of integers
int* ptr = numbers;
// 'ptr' points to the first element of the array.
ptr++;
// Move 'ptr' to the next integer in the array. ptr now points to the second element (20) in the array.
ptr--;
// Move 'ptr' back to the first element of the array. ptr points back to the first element (10) of the array.

5
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Understanding pointer arithmetic.
int numbers[] = {10, 20, 30, 40, 50};// this line is from previous slide to only show the array
ptr = ptr + 2; // continuation of the previous code lines
// Move 'ptr' two elements forward. ptr points to the third 3rd element (30) of the array.
int thirdElement = *ptr;
// 'thirdElement' now contains the value 30. By dereferencing ptr, you retrieve the value that ptr points to.
int* anotherPtr = numbers + 4;
// 'anotherPtr' points to the 5th element.
int elementsBetween = anotherPtr - ptr;
// Calculates the number of elements between 'ptr' and 'anotherPtr’.
// In this case, elementsBetween will be 5-3 = 2 because there are two elements between the third and fifth
elements in the array.

6
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Working with multidimensional arrays using pointers.
❑ Multidimensional arrays are arrays of arrays, where data is organized in a tabular form with rows and
columns. In C and C++, multidimensional arrays are typically stored in memory as contiguous blocks
of data. Pointers provide a way to navigate this memory efficiently. When you declare a pointer to a
multidimensional array, it allows you to access individual elements and traverse the array by
adjusting the pointer position. Keep it in mind that rows and columns starts from 0, 1, and 2…

int matrix[4][3] = { {11, 12, 13}, {14, 15, 16}, {17, 18, 19}, {110, 111, 112} };

int(*ptr)[3] = &matrix[1]; // Points to the second row (index 1) of matrix and the pointer have access on 3 arrays

7
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Working with multidimensional arrays using pointers.

int main() {
int matrix[4][3] = { {11, 12, 13}, {14, 15, 16}, {17, 18, 19}, {110, 111, 112} };

// Create a pointer to the second row of the matrix


int(*ptr)[3] = &matrix[1]; // Points to the second row (index 1)

// Access the values at the addresses of individual elements in the second row
int value_1 = (*ptr)[0]; // int address_1 = &(*ptr)[0]; for address of this pointer
int value_2 = (*ptr)[1]; // int address_2 = &(*ptr)[1]; for address of this pointer
int value_3 = (*ptr)[2]; // int address_3 = &(*ptr)[2]; for address of this pointer

// Print the values


std::cout << "Value at Matrix[1][0]: " << value_1 << std::endl;
std::cout << "Value at Matrix[1][1]: " << value_2 << std::endl;
std::cout << "Value at Matrix[1][2]: " << value_3 << std::endl;
8
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Working with multidimensional arrays using pointers.

int main() {
int matrix[4][3] = { {11, 12, 13}, {14, 15, 16}, {17, 18, 19}, {110, 111, 112} };

// Create a pointer to the second row of the matrix


int(*ptr)[3] = &matrix[1]; // Points to the second row (index 1)

int* Address_1 = (ptr)[0]; //either this format of argument


int* Address_2 = &(*ptr)[1];// or this format
int* Address_3 = &(*ptr)[2];

// Print the values


std::cout << "Address at Matrix[1][0]: " << Address_1 << std::endl;
std::cout << "Address at Matrix[1][1]: " << Address_2 << std::endl;
std::cout << "Address at Matrix[1][2]: " << Address_3 << std::endl;

9
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Working with multidimensional arrays using pointers.

int matrix[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

You can use nested loops and pointers to traverse the entire multidimensional array:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int element = (*ptr)[j]; // Access each element in the current row.
// Perform operations with 'element'.
}
ptr++; // Compare it with another format of asking to move to the next row.
}

10
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

❑ A linked list is a collection of nodes. Each node has two parts: data and a reference to the next
node. Unlike arrays, linked lists don't require contiguous memory allocation. They can easily grow
or shrink during runtime. Common types of linked lists include:

➢ Singly linked lists (each node points to the next),

➢ Doubly linked lists (each node points to both the next and previous), and

➢ Circular linked lists (the last node points back to the first).

11
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.
❑ #include <iostream>

❑ // Define a node structure.


❑ struct Node {
❑ int data; //Value of the data container in memory
❑ Node* next; // Address of the data to be able to point to the next node
❑ };

❑ int main() {
❑ // Create nodes. Here nullptr has three address because of the Node structure definition
❑ Node* head = nullptr; // Initialize an empty Address for first node we call it head
❑ Node* second = nullptr; // Initialize an empty Address for second node we call it second
❑ Node* third = nullptr; // Initialize an empty Address for third node we call it third

12
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.
// Allocate memory for the first node. Nod structure has the data and the address of the next by means of the
pointer
❑ head = new Node(); // new modifies head from null
❑ second = new Node(); // Allocate memory for the second node.
❑ third = new Node(); // Allocate memory for the third node.

❑ // Assign data and link for the created nodes to manage the nodes. The arrow -> is an operator used in C++
to access members of a structure or class through a pointer
❑ head->data = 1; // assigns the value 1 to the ‘data’ member of the ‘head’ node.
❑ head->next = second;

❑ second->data = 2;
❑ second->next = third;

❑ third->data = 3;
❑ third->next = nullptr; // Mark the end of the list. 13
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

❑ // Traverse and print the linked list.


❑ Node* current = head; //we give the address of head node to the ‘current’ variable
// creating a conditional loop to see what addresses and data assigned to the nodes
❑ while (current != nullptr) {
❑ std::cout <<"Data:" << current->data << " Address:" << current->next << " \n";
❑ current = current->next; } // changing the current address by ‘next’ which contains address of the nodes
as we earlier defined in a structure by Node* next
❑ return 0;}

Data:1 Address:000002543E463250
Data:2 Address:000002543E463610
Data:3 Address:0000000000000000

14
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

❑ In C++, pointers play a crucial role in representing and manipulating tree structures, such as:
1. Binary trees,
2. Binary search trees
3. Hierarchical data structures
❑ Trees are used to organize data hierarchically, making them suitable for tasks like:
1. Searching
2. Sorting
3. Conducting complex relationships
❑ In tree structures, a pointer points to a node, and each node can have multiple child nodes. The organization
of nodes and their connections forms the tree's structure. Pointers are used to traverse the tree, access data,
and manipulate nodes.
❑ A common type of tree structure is the Binary tree, where each node can have at most two children:
1. Left child
2. Right child
Pointers to these children are used to navigate the tree.
15
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

#include <iostream>
// Define a binary tree node structure by assigning the left and right nodes’ address

struct TreeNode {
int data;
TreeNode* left;
TreeNode* right;

// This structure has two values: one for TreeNode (root) and the other for data- It also has to addresses one for
left one for right

TreeNode(int val) : data(val), left(nullptr), right(nullptr) {} // This is a constructor see the next slide
};

16
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

Constructor:

TreeNode(int val) : data(val), left(nullptr), right(nullptr) {}

TreeNode(int val): This is the constructor declaration. It specifies a constructor for the TreeNode structure that
takes an integer argument val. This argument typically represents the data or value that you want to assign to the
data member of the TreeNode object being constructed.

: (Initialization List): This colon is used to introduce the initialization list, which is a way to initialize the member
variables of the TreeNode object that is being created.

17
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

Constructor:

TreeNode(int val) : data(val), left(nullptr), right(nullptr) {}

data(val): This part of the initialization list assigns the value of val to the data member, initializing the node's data.

left(nullptr): This part initializes the left member of the TreeNode object with nullptr, indicating an initially empty
or unconnected left child.

right(nullptr): This part initializes the right member of the TreeNode object with nullptr, indicating that the right
child of the node is initially unconnected.

18
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

int main() {
// Create tree nodes and establish connections.
TreeNode* root = new TreeNode(10); // Create the root node and initialize it with a value of 10.
root->left = new TreeNode(5); // Create a left child node with a value of 5 and connect it to the root.
root->right = new TreeNode(15); // Create a right child node with a value of 15 and connect it to the root.

// Access and print data using pointers.


std::cout << "Root: " << root->data << std::endl;
std::cout << "Left Child: " << root->left->data << std::endl;
std::cout << "Right Child: " << root->right->data << std::endl;

// Clean up memory
delete root->left;
delete root->right;
delete root;
return 0;} 19
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

❑ Graphs are versatile data structures used to represent complex relationships between entities. In
C++, graphs are often implemented using pointers to represent nodes (vertices) and edges. Pointers
play a crucial role in linking nodes and navigating the graph.

❑ A graph is a collection of nodes (vertices) and edges (connections) that link these nodes. Each node
can be connected to one or more other nodes. In C++, you can represent a graph using structures or
classes for nodes, and pointers to establish connections between nodes.

❑ Pointers are used to navigate the graph, visit neighboring nodes, and perform various graph
algorithms:
1. Breadth-first search (BFS)
2. Depth-first search (DFS)

20
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

#include <iostream>
#include <vector>

// Define a graph node structure. We define a GraphNode structure to represent a node in the graph.
each node has data and a vector of pointers to its neighboring nodes.
struct GraphNode {
int data;
std::vector<GraphNode*> neighbors;

GraphNode(int val) : data(val) {} // This is a constructor please see the next slide
};

21
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

❑ Constructors in C++:

GraphNode(int val) : data(val) {}


GraphNode(int val): This is the constructor declaration. It takes an integer argument val, which
represents the data value that you want to assign to the data member of the GraphNode object being
constructed.
: colon : Start before a list of members.
data(val): It assigns the value of the val argument to the data member. Essentially, it sets the data
member of the newly created GraphNode object to the value passed as val. So, when you create a
GraphNode object like this:

22
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

GraphNode(int val) : data(val) {}


➢ The {} braces allow you to provide the implementation or code that initializes the object's state or
performs any other necessary setup.
➢ In this case, the constructor is defined, but it lacks a body, so it's essentially an empty constructor. It
doesn't perform any specific initialization or setup.

GraphNode* nodeA = new GraphNode(2023);


It means you are creating a new GraphNode object named nodeA, and you're passing the value 1 as
an argument to the constructor. The constructor, in turn, initializes the data member of nodeA with
the value 1. This allows you to set the initial data value for each node when you create them.

23
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

int main() {
// Create graph nodes.
GraphNode* nodeA = new GraphNode(100);
GraphNode* nodeB = new GraphNode(200);
GraphNode* nodeC = new GraphNode(300);

❑ In these lines of code, you are creating three nodes (nodeA, nodeB, and nodeC) for a graph data
structure. Each node is assigned a unique integer value: nodeA has a value of 100, nodeB has a
value of 200, and nodeC has a value of 300.
❑ These nodes will serve as individual points or entities within the graph, and the assigned values can
represent various kinds of data or information associated with each node.

24
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Advanced data structures like linked lists, trees, and graphs with pointers.

// Establish connections between nodes.


nodeA->neighbors.push_back(nodeB);
nodeA->neighbors.push_back(nodeC);
nodeB->neighbors.push_back(nodeC); //IMPORTANT: UN-DIRECTED OR BIDIRECTIONAL
//Without it, your graph would represent an edge from A to B and from A to C, but it wouldn't
represent the edge from B to C…. return 0;}

❑ In the line nodeA->neighbors.push_back(nodeB);, you are adding nodeB as a neighbor to nodeA


within a graph data structure. This is typically done using a container like a vector to maintain a list
of neighboring nodes.
❑ The push_back function is used to add nodeB to the end of the list of neighbors for nodeA. In
graph representation, this operation establishes a connection or edge between nodeA and nodeB,
indicating that they are adjacent or connected in the graph.
25
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Exploring function pointers and their applications.

❑ In C++, a function pointer is a variable that can store the memory address of a function. It provides
a way to call a function indirectly through the pointer, making it possible to choose and execute
different functions at runtime.
❑ Function pointers are commonly used for?:
1. Callbacks
2. Implementing custom function dispatch
3. Enabling dynamic behavior in programs

26
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Exploring function pointers and their applications.

#include <iostream>
// Define two functions with the same signature.
int add(int a, int b) {
return a + b;}
int subtract(int a, int b) {
return a - b;}

int main() {
// Declare a function pointer.
int (*operation)(int, int);

27
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Exploring function pointers and their applications.

// Initialize the function pointer with the 'add' function.


operation = add;

// Use the function pointer to call 'add'.


int result = operation(10, 5);
std::cout << "Result of 'add': " << result << std::endl;

// Change the function pointer to point to the 'subtract' function.


operation = subtract;

// Use the function pointer to call 'subtract'.


result = operation(10, 5);
std::cout << "Result of 'subtract': " << result << std::endl;
return 0;}
28
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Using function pointers for callback mechanisms.

❑ In software development, callback mechanisms are a powerful way to customize or extend the
behavior of a function without altering its core code. Function pointers play a crucial role in
implementing these mechanisms. Here are the general step to realize such useful mechanism:

Step1: Define Callback Function Type


Step2: Customize Callback Behavior
Step3: Initialize Callback Function Pointer
Step4: Assign Callback Function
Step5: Use the Callback Function

29
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Using function pointers for callback mechanisms.

#define _USE_MATH_DEFINES // Define this to enable M_PI 3.14


#include <iostream>
#include <cmath>

// Step 1: Define Callback Function Type (you can go without typedef also)
typedef double (*Callback)(double, int); // the pointer Callback creates address for a function with two types of data

// Function to calculate the factorial of a number


double Factorial(int n) {
double result = 1.0;
for (int i = 1; i <= n; ++i) {
result *= i;}
return result;}

30
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Using function pointers for callback mechanisms.

// Step 2: Customize Callback Behavior by Implementing Different Functions

//Sine function using Teylor series Callback Function1 is Sine_F


double Sine_F(double x, int t) {
return (pow(-1, t) * pow(x, 2 * t + 1)) / Factorial(2 * t + 1);
}

//Cosine function using Teylor series Callback Function2 is Cosine_F


double Cos_F(double x, int t) {
return (pow(-1, t) * pow(x, 2 * t)) / Factorial(2 * t);
}

31
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Using function pointers for callback mechanisms.

// Step 3: Initialize Callback Function Pointer


Callback Call_back; // Assigning the address of pointer (Callback) to the Call_back

int main() {
// Step 4: Assign Callback Function1 or 2 to the Pointer (call_back)
Call_back = Sine_F; // For sine series
// OR
// Call_back = Cos_F; // For cosine series

//It is also possible to declare like this: Callback call_back = Sine_F; but we already initialized in step3

// Use a constant for PI


const double PI = M_PI;
std::cout << "Result: " << result << std::endl;
return 0;} 32
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Using function pointers for callback mechanisms.

// Step 5: Use the Callback Function


double angle = PI / 4.0; // 45 degrees in radians
double output = 0.0;
for (int t = 0; t < 5; ++t) {

// Use the Callback Function to customize the series calculation.

result += Call_back(angle, t);


}

std::cout << "Result: " << output << std::endl;


return 0;}
33
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Implementing dynamic function dispatch with pointers.

❑ Dynamic function dispatch is a fundamental concept in OOP that allows you to call the appropriate
method or function based on the runtime type of an object.
❑ In C++, dynamic function dispatch is primarily achieved through pointers to base classes and virtual
functions. This mechanism enables polymorphism, which is a key feature of object-oriented programming.
For mplementing Dynamic Function Dispatch with Pointers in C++, we can go through:

• Polymorphism
• Base Class and Derived Classes
• Virtual Functions
• Pointers to Base Class

34
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Implementing dynamic function dispatch with pointers.

❖ Polymorphism: Polymorphism allows objects of different classes to be treated as objects of a common


base class, facilitating flexibility in object-oriented programming.
❖ Base Class and Derived Classes: Base classes serve as the foundation for derived classes, which inherit
their attributes and methods, enabling code reuse and polymorphism.
❖ Virtual Functions: Virtual functions are functions declared in a base class and overridden in derived classes,
enabling dynamic function dispatch based on the runtime type of objects.
❖ Pointers to Base Class: Pointers to base classes are used to refer to objects of derived classes, allowing for
polymorphic behavior and dynamic function calls.

35
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Understanding double pointers and their uses.

❑ In C and C++, a double pointer is a pointer to a pointer. It's a variable that holds the memory
address of another pointer. Double pointers are often used when you need to work with:

1. Dynamically allocated multi-dimensional arrays


2. Manipulate pointers in functions
3. Modify a pointer from within a function

36
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Understanding double pointers and their uses.
#include <iostream>
int main() {
int x = 10; // An integer variable
int *ptr1 = &x; // A pointer to x
int **ptr2 = &ptr1; // A double pointer to ptr1
// Display the original variable and its value OUTPUT:
std::cout << "Original Variable (x): " << x << std::endl; Original Variable (x): 10
// Modify the value using the pointer Modified Variable (x): 20
*ptr1 = 20; Final Modified Variable (x): 30
// Display the modified value
std::cout << "Modified Variable (x): " << x << std::endl;
// Modify the value using the double pointer
**ptr2 = 30;
// Display the final modified value
std::cout << "Final Modified Variable (x): " << x << std::endl;
return 0;} 37
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Understanding double pointers and their uses.
#include <iostream>
int main() {
int x = 10; // An integer variable Pointers and double pointers can be reassigned!
int y = 20; References can’t be reassigned!
int ref = x; Original Variable (x): 10
int* ptr1 = &x; // A pointer to x
ptr1: 10
int** ptr2 = &ptr1; // A double pointer to ptr1
std::cout << "Original Variable (x): " << x << std::endl; Modified Variable (x): 10
std::cout << "ptr1: " << *ptr1 << std::endl; Modified ptr1 directly: 20
ptr1 = &y; Modified ptr1 by ptr2: 30
std::cout << "Modified Variable (x): " << x << std::endl; Final Modified Variable (x): 10
std::cout << "Modified ptr1 directly: " << *ptr1 << std::endl; x = 10, y = 30, ref = 30
**ptr2 = 30;
std::cout << "Modified ptr1 by ptr2: " << *ptr1 << std::endl;
std::cout << "Final Modified Variable (x): " << x << std::endl;
ref = y;
std::cout << "x = " << x << ", y = " << y << ", ref = " << ref << std::endl;
return 0;} 38
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Function pointers to handle arrays of functions.

❑ In C and C++, you can use function pointers to create arrays of functions. This technique is
particularly useful when you want to call different functions dynamically based on certain
conditions or inputs. Function pointers provide flexibility and enable you to choose which function
to execute at runtime.
#include <iostream>
// Initiate function array pointer
// Define Array of functions based on number of function
// Define operations of the given function
// call function and variables by their index array
//output

39
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Function pointers to handle arrays of functions.

Typedef int (*FunctionPtr)(int, int);


FunctionPtr functionArray[3];

functionArray[0] = &Add;
functionArray[0] = &Subtract;
functionArray[0] = &Multiply;

//Define functions
int a = 10;
int b = 20;
Int result = functionArray[0](a,b); // Calls the Add function

40
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Real-world examples of complex pointer-to-function scenarios.

o Event Handling in GUI Libraries


o Operating System Interrupt Handling
o Plug-in Systems
o Command Pattern in Design Patterns
o Callback Functions in APIs
o Device Drivers
o Sorting Algorithms
o Game Engines
o Multithreaded Programming
o Dynamic Libraries and Dynamic Loading
o State Machines
o Simulation Software

41
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Memory safety with pointers in languages like Rust.

❑ Rust and C++ are distinct languages with their own compilers and ecosystems. To use Rust, you
need to install the Rust programming language and its compiler separately, and it is not a header
or part of the C++ language. Rust offers a different approach to system-level programming,
focusing on memory safety and concurrency, while C++ provides a long-established approach
with its own set of features and libraries.

❑ Pointers in C++ do not provide the same level of safety as Rust due to differences in their
language design and memory management models. While C++ provides mechanisms to work
with pointers, it lacks the strong memory safety guarantees that Rust offers.

42
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Strategies for avoiding common pointer errors (e.g., null pointer, dangling pointer).

Common errors with pointers


Null Pointer:
A null pointer is a pointer that does not point to any valid memory location. In C++, it is
often represented as ‘nullptr’. Null pointers are used to indicate that a pointer does not
currently reference any object or memory.

Dangling Pointer:
A dangling pointer is a pointer that continues to reference a memory location after the
memory it points to has been deallocated (freed) or goes out of scope. Accessing a
dangling pointer can lead to undefined behavior or crashes.

43
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Strategies for avoiding common pointer errors (e.g., null pointer, dangling pointer).
Common solutions for solving errors

o Initialize Pointers: Always initialize pointers when declaring them.


o Nullify Pointers After Deletion: Set pointers to null or ‘nullptr’ after deleting the object they
o Check for Null Pointers: Before dereferencing a pointer, check if it's null (nullptr in C++).
o Pointer Ownership Rules: Establish clear rules for pointer ownership.
o Use Constants: Use ‘const’ and ‘constexpr’ to indicate fixity when appropriate.
o Use Smart Pointers: Consider using smart pointers (e.g., std::shared_ptr, std::unique_ptr) in
C++ to manage memory automatically.

44
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Smart pointers in C++ and their role in memory management.

Smart Pointers: They are C++ objects that act as wrappers around raw pointers, providing automatic
memory management. They help prevent memory leaks and manage the lifetime of dynamically
allocated objects. We have two smart pointers: Shared and Unique pointers.
1. Shared Pointers: It is a type of smart pointer in C++ that allows multiple shared pointers to
share ownership of the same dynamically allocated object. Memory is automatically
deallocated when the last shared pointer that owns it goes out of scope, preventing premature
deallocation.
std::shared_ptr<int> smart= std::make_shared<int>(2032);
2. Unique Pointers: It is a type of smart pointer in C++ that represents exclusive ownership of a
dynamically allocated object. Unlike shared pointers, only one unique pointer can own the
object, and when the unique pointer goes out of scope, the associated memory is automatically
deallocated.
std::unique_ptr<int> smart = std::make_unique<int>(2023);

45
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Memory safety with pointers in languages like Rust.
Memory Safety with Pointers in Rust:
Memory safety is a critical concern in systems programming languages like Rust. Rust is designed to provide
memory safety guarantees while still allowing low-level control over hardware resources. One of Rust's
strengths is its powerful and strict type system. The Rust compiler enforces memory safety guarantees at
compile time, catching many potential issues before the code is even run.
how Rust achieves memory safety with pointers:
1. Ownership System
2. Borrowing and References
3. No Null Pointers
4. Ownership Transfers
5. Lifetimes
6. Smart Pointers
7. Unsafe Blocks
8. Compiler-Enforced Guarantees

46
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Memory safety with pointers in languages like Rust.
Ownership System:

In C++, ownership of resources (typically memory) is primarily managed manually by the programmer. C++
does not have a built-in ownership system like Rust, but it relies on a set of conventions and programming
practices to manage ownership. Here's an overview of how ownership works in C++:
✓ Dynamic Memory Allocation: Memory is allocated manually using operators like new and new[] for
objects on the heap (dynamic memory location).
✓ Ownership Transfer: Ownership of resources can be transferred between objects using move
semantics.
✓ Ownership Release: The delete operator is used to deallocate memory and release ownership.
✓ Manual Resource Management: Resources like file handles are manually managed by acquiring and
releasing them explicitly.

47
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Memory safety with pointers in languages like Rust.
Ownership System:

✓ Ownership Conventions: C++ follows guidelines like the "Rule of Three" and "Rule of Five" to ensure
proper resource management.
✓ Smart Pointers (Optional): C++ provides smart pointers that can automatically manage memory,
reducing the risk of memory leaks.
✓ Resource Management Libraries: Developers can use libraries like Boost.Asio and Boost.Filesystem
to assist in managing specific types of resources.

48
CSI2372 - Advanced Programming Concepts with C++
Module 1: Foundations of C++ Programming
Session 3: Pointers, Memory Management, and Efficiency
Memory safety with pointers in languages like Rust.
Rule of Three:
The Rule of Three states that if a class manages a dynamically allocated resource (like memory), it should
define or delete the copy constructor, copy assignment operator, and destructor.
This ensures proper handling of resource ownership, preventing memory leaks and double deletions when
objects are copied or destroyed.

Rule of Five:(Developed version of Rule of Three)


The Rule of Five extends the Rule of Three for modern C++ (C++11 and beyond) and includes defining or
deleting the move constructor and move assignment operator, in addition to the copy constructor, copy
assignment operator, and destructor.
It's used when a class manages resources and needs to efficiently transfer ownership of those resources
through moves rather than costly copies, improving performance.

49
Thank You

50
Password

51
Password-CSI-Monday

52

You might also like