Skip to main content
C++ Fundamentals for Beginners to Advanced
CHAPTER 21 Beginner

Exception Handling in C++

Updated: May 17, 2026
5 min read

# CHAPTER 21

Exception Handling

1. Introduction

Errors happen. A user types a letter instead of a number, a file goes missing, or a division by zero occurs. If you don't handle these errors, the program crashes abruptly (Segmentation Fault or Floating Point Exception). Exception Handling allows you to gracefully catch these errors, report them, and keep the program running.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Understand the try, throw, and catch keywords.
  • Catch multiple types of exceptions.
  • Understand the "catch-all" handler catch(...).
  • Create Custom Exception classes.
  • Ensure Exception Safety.

3. The Big Three: Try, Throw, Catch

  • try: A block of code that you suspect might cause an error.
  • throw: Used to manually trigger an error when a problem is detected.
  • catch: A block of code that handles the error if one is thrown.
cpp
1234567891011121314151617181920212223
#include <iostream>
using namespace std;

int main() {
    int denominator = 0;
    int numerator = 10;
    
    try {
        if (denominator == 0) {
            // 1. Detect the error and THROW it
            throw "Error: Division by zero!"; 
        }
        // If thrown, this line is SKIPPED
        cout << (numerator / denominator) << endl; 
        
    } catch (const char* msg) { 
        // 2. CATCH the error and handle it gracefully
        cout << msg << endl;
    }
    
    cout << "Program continues running..." << endl;
    return 0;
}

*Output:*

text
12
Error: Division by zero!
Program continues running...

4. Catching Multiple Exceptions

A try block can have multiple catch blocks depending on what type of data is thrown (an int, a string, an object, etc.).
cpp
123456789
try {
    int age = -5;
    if (age < 0) throw 404; // Throw an int
    if (age > 120) throw "Invalid age"; // Throw a string
} catch (int errorNum) {
    cout << "Error Code: " << errorNum << endl;
} catch (const char* errorMsg) {
    cout << "Error: " << errorMsg << endl;
}

5. The Catch-All Handler

If you want to catch *any* exception that might be thrown, regardless of its data type, use catch(...).
cpp
12345
try {
    throw 5.5; // Throws a double
} catch (...) { // Catches EVERYTHING
    cout << "An unknown error occurred!" << endl;
}

6. Standard Exceptions (std::exception)

C++ provides a standard library of exceptions <stdexcept>. Instead of throwing raw strings or ints, it is best practice to throw standard objects like std::invalidargument or std::outof_range.
cpp
123456789101112
#include <iostream>
#include <stdexcept> // Required for standard exceptions
using namespace std;

int main() {
    try {
        throw runtime_error("Database connection failed!");
    } catch (const exception& e) { // Catching by reference is Best Practice!
        cout << "System Error: " << e.what() << endl; // what() prints the message
    }
    return 0;
}

7. Custom Exceptions

You can create your own exception classes by inheriting from std::exception.
cpp
1234567891011121314151617181920
#include <iostream>
#include <exception>
using namespace std;

class OverheatingException : public exception {
  public:
    // Override the what() method
    const char* what() const throw() {
        return "CRITICAL: Engine temperature exceeded safe limits!";
    }
};

int main() {
    try {
        throw OverheatingException();
    } catch (const OverheatingException& e) {
        cout << e.what() << endl;
    }
    return 0;
}

8. Mini Project: Safe Calculator

cpp
12345678910111213141516171819202122232425
#include <iostream>
#include <stdexcept>
using namespace std;

double divide(double a, double b) {
    if (b == 0) {
        throw invalid_argument("Division by zero is mathematically undefined.");
    }
    return a / b;
}

int main() {
    double num1, num2;
    cout << "Enter two numbers to divide: ";
    cin >> num1 >> num2;
    
    try {
        double result = divide(num1, num2);
        cout << "Result: " << result << endl;
    } catch (const invalid_argument& e) {
        cout << "CALCULATOR ERROR: " << e.what() << endl;
    }
    
    return 0;
}

9. Memory-Level Explanation

When an exception is thrown, the C++ runtime performs Stack Unwinding. It looks at the current Stack Frame. If there is no catch block, it destroys that frame (cleaning up local variables) and moves down to the caller's frame. It continues unwinding the stack until it finds a catch block. If it reaches main() and finds no catch block, the OS forcefully terminates the program.

10. Common Mistakes

  • Memory Leaks during Stack Unwinding: If you allocate memory with new, and an exception is thrown *before* you call delete, that memory is leaked. (This is why Smart Pointers are used in Modern C++!).
  • Catching by Value instead of Reference: catch(exception e) creates a copy of the exception object, which is slow and can cause "object slicing". Always use catch(const exception& e).

11. Exercises

  1. 1. Write a program that asks for a user's age. If the age is negative, throw an invalidargument exception.
  1. 2. Create an array of size 5. Ask the user for an index to access. If the index is > 4, throw an outof_range exception.

12. MCQ Quiz with Answers

Question 1

Which keyword is used to trigger an exception?

Question 2

Which block contains the code that handles the error?

Question 3

How do you catch all types of exceptions?

Question 4

What is the base class for all standard C++ exceptions?

Question 5

Which method of std::exception returns the error message string?

Question 6

What happens during Stack Unwinding?

Q7. Is it better to catch exceptions by value or by reference? a) By value b) By reference (e.g., catch (const exception& e)) Answer: b) By reference
Question 8

What happens if an exception is thrown but never caught?

Q9. Can you throw an integer instead of an object? a) Yes b) No Answer: a) Yes (e.g., throw 404;)
Question 10

Why is try-catch preferred over simple if statements for error handling?

13. Interview Questions

  • Q: Explain Stack Unwinding in the context of C++ Exceptions.
  • Q: Why should you catch exceptions by const reference?
  • Q: Explain the noexcept specifier in Modern C++. (Answer: It tells the compiler that a function will *never* throw an exception, allowing the compiler to optimize the code heavily).

14. Summary

Exception handling (try, throw, catch) provides a structured way to handle runtime errors without crashing the program. By utilizing std::exception and catching by reference, you can build robust, error-tolerant software.

15. Next Chapter Recommendation

In Chapter 22: Standard Template Library (STL), we will discover the most powerful feature of C++: a massive library of ready-to-use data structures (Vectors, Maps) and algorithms that will save you hundreds of hours of coding.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·