Miscellaneous Topics
COS2614 - Programming: Contemporary Concepts · C++ Language Reference
Miscellaneous Topics
This topic covers various important concepts in C++ programming, particularly focusing on arrays, pointers, memory allocation, and error handling. Understanding these concepts is essential for writing efficient and safe C++ programs.
Key idea: After studying this topic, you should be able to:
- Understand the different kinds of arrays in C++.
- Perform valid pointer operations.
- Handle memory allocation failures effectively.
Different Kinds of Arrays
In C++, arrays can hold primitive types, such as int, char, and byte. They can also hold objects, which allows for backward compatibility with C's arrays of structs. However, arrays of objects should only be used for uniform collections of identical structures. For collections of similar polymorphic objects, it is better to use containers like QList (from Qt) or vector (from the Standard Template Library or STL). These containers are dynamic arrays that manage memory allocation and deallocation automatically.
Example of Using Arrays
#include <iostream>
using namespace std;
int main() {
int numbers[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) {
cout << numbers[i] << " ";
}
return 0;
}Valid Pointer Operations
Pointers are variables that store memory addresses. You can perform several operations with pointers:
Pointer Creation
A pointer can be created from:
- A constant pointer, such as an array name.
- An address obtained using the address-of operator
&. - A value from a dynamic memory allocation operator, such as
new.
Pointer Assignment
You can assign one pointer to another if they are of the same type or a derived type. A void* pointer can be assigned to any type without casting. However, a non-void* pointer requires an explicit cast when assigned to a different type.
Pointer Arithmetic
You can increment or decrement pointers, or add/subtract integers. Pointer arithmetic is only valid within the bounds of the array, except for one position beyond the end of the array.
Example of Pointer Arithmetic
#include <iostream>
using namespace std;
int main() {
int arr[3] = {10, 20, 30};
int* p = arr;
cout << *(p + 1) << " "; // Outputs 20
return 0;
}Pointer Comparison
Pointers can be compared using relational operators, such as == and !=.
Indirection and Indexing
You can access the value pointed to by a pointer using the indirection operator *. Additionally, you can use the array index operator with pointers, which the compiler interprets as *(p + i).
Example of Indirection
#include <iostream>
using namespace std;
int main() {
int value = 42;
int* ptr = &value;
cout << *ptr << " "; // Outputs 42
return 0;
}Watch out: Be careful when using pointer arithmetic. Ensure you do not exceed the bounds of the array, as this can lead to undefined behaviour.
Handling Memory Allocation Failures
new, it may fail if there is not enough memory available. The C++ standard specifies thatnew should throw a bad_alloc exception if it fails. You can handle this exception using a try-catch block.Example of Handling Memory Allocation Failures
#include <iostream>
#include <new>
using namespace std;
void memoryEater() {
double* ptr;
try {
ptr = new double[50000000];
} catch (bad_alloc& e) {
cerr << "Memory allocation failed: " << e.what() << endl;
}
}
int main() {
memoryEater();
return 0;
}Using set_new_handler()
You can also specify a custom function to be called when new fails by using set_new_handler(). This allows you to define what should happen in case of a memory allocation failure.
Example of set_new_handler()
#include <iostream>
#include <cstdlib>
#include <new>
using namespace std;
void out_of_store() {
cerr << "Memory allocation failed. Exiting..." << endl;
exit(1);
}
int main() {
set_new_handler(out_of_store);
double* ptr = new double[50000000];
return 0;
}Watch out: Always check for memory leaks and ensure that allocated memory is freed when it is no longer needed.
Summary
- Arrays can hold primitive types and objects, but use containers for dynamic memory management.
- Pointers allow for various operations, including creation, assignment, arithmetic, and comparison.
- Handle memory allocation failures using exceptions and custom handlers.
Check your understanding
- What are the differences between arrays and containers in C++?
- Explain how pointer arithmetic works and provide an example.
- What should you do when a memory allocation fails?
- How can you use
set_new_handler()in your programs?