In this instance, we are going to explore a C++ application that demonstrates runtime exceptions. However, prior to delving into the implementation of the runtime exceptions, it is essential to understand the concept of exceptions or how exception handling is done in C++.
Exceptions in C++:
An anomaly in C++ is a situation that arises during program execution. The software has the ability to generate exceptions, notifying when an error state is detected during abnormal operations. More precisely, runtime exceptions are those that surface while the program is in progress, in contrast to compile-time issues that the compiler detects.
C++ Exception Handling :
Programmers can effectively handle runtime errors using the inherent exception management features available in C++. When dealing with exceptions in C++, three key keywords come into play:
- A code snippet that allows for handling exceptions.
- When an error is encountered within the try block, an exception is raised.
- Utilized to explicitly raise an exception.
- The software may generate an exception object of a specific category when an error is identified.
- catch statement is the code block responsible for handling exceptions.
If any exception occurs within the try block, a corresponding catch block is executed.
Example programs to demonstrate runtime Exceptions in C++:
1. Divide by zero exception:
#include<iostream>
int main()
{
int numerator = 10;
int denominator = 0;
try {
if (denominator == 0) {
throw "Divide by zero exception";
}
int result = numerator / denominator;
std::cout << "Result: " << result << std::endl;
} catch (const char* msg) {
std::cerr << "Error: " << msg << std::endl;
}
return 0;
}
Output:
Explanation:
The objective of this program is to perform division by zero on an integer. Consequently, dividing by zero is undefined in mathematics. If an attempt is made to perform this calculation, a runtime exception will be raised. In this case, a try-catch block is employed to handle the exception.
2. Array Out of Bounds Exception:
#include<iostream>
#include <vector>
int main()
{ std::vector<int> v = { 8,3,6,1,9 };
v[0] = 12; // arr is now: { 12, 3, 6, 1, 9 }
//v[5] = 19; // Undefined behavior: index is out of bounds
// (No bounds checking was done here)
try
{
v.at(5) = 19;
// use at() function to access element
}
catch (...)
{
std::cout << "Out-of-bounds exception captured!\n";
}
return 0;
}
}
Output:
Explanation:
In the program mentioned earlier, an attempt was made to retrieve an element from a vector using an index that exceeds the bounds. When accessing an element outside the valid range, the at method is employed, triggering an exception std::outofrange. To handle this exception, a try-catch block should be implemented.
3. Null Pointer Exception:
#include<iostream>
int main() {
int* ptr = nullptr;
if (ptr == nullptr) {
std::cerr << "Error: Null pointer exception" << std::endl;
return 1; // Return an error code indicating failure
}
std::cout << "Value: " << *ptr << std::endl; // Attempting to dereference a null pointer
return 0;
}
Output:
Explanation:
In this code snippet, we attempt to access the memory location pointed to by a null pointer (ptr). It is common for a runtime exception to occur when dereferencing a null pointer, leading to unpredictable program behavior. To handle this situation, we employ a try-catch block to catch the exception and display an error message.
4. File I/O Exception:
#include<iostream>
#include <fstream>
int main() {
try {
std::ifstream file("nonexistent_file.txt");
if (!file) {
throw std::runtime_error("File not found");
}
int value;
file >> value;
std::cout << "Value: " << value << std::endl;
file.close();
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
Output:
Explanation:
In this code snippet, we are trying to access a file that does not exist. When attempting to open a non-existent file, a runtime exception is triggered. To handle this situation, we employ a try-catch block to capture the exception and display an error message to the user.
5. Vector Iterator Exception:
#include<iostream>
#include<vector>
#include<stdexcept>
int main()
{
std::vector<int>v={9,8,7,6,5};
try
{
for(int i=0;i<v.size();i++)
{
cout<<v.at(i)<<endl;
}
catch(const std::out_of_range& e)
{
cerr<<?Error?<<e.what()<<endl;
}
return 0;
}
Output:
Explanation:
Utilizing iterators, the program attempts to traverse through a vector. However, there is an inadvertent increment of the end iterator within the loop condition, leading to a potential undefined behavior and triggering a runtime exception. The program is designed to capture any exception inherited from std::exception and display an error message accordingly.
6. String Index Out of Bounds Exception:
#include<iostream>
#include<string>
#include<stdexcept>
int main()
{
std::string s =?Hello,JTP?;
try
{
char c=str.at(25);
cout<<?char at index 25:?<<ch<<endl;
}
catch(const std::out_of_range& e)
{
cerr<<?error?<<e.what()<<endl;
}
return 0;
}
Output:
Explanation:
This code snippet sets up a string variable named str with the content "Hello, World!". Following that, an attempt is made to retrieve the element at position 20 using the at method. Consequently, if the length of the string is shorter than 20, it will trigger a std::outofrange exception.