Click Here!
home account info subscribe login search FAQ/help site map contact us


 
Brief Full
 Advanced
      Search
 Search Tips
[an error occurred while processing this directive]
Previous Table of Contents Next


Comments

A thorough understanding of pointers is required when dealing with allocated memory. This is because the new expression returns a pointer to the allocated type.

Allocating memory at runtime helps with the efficiency of an application. Massive amounts of data storage do not have to be statically declared at compile time. Memory use can be tailored to the needs of the application.

Dynamically allocating memory can also cause frustration for many development teams. You must always ensure that allocated memory is properly reclaimed (deleted) when it is no longer required. This is the main cause of memory leaks.

1.7 Create a program to perform error handling, specifically exception handling?

Problem

I have heard that exception handling is a way to respond to errors encountered during the execution of a program. I have seen examples of C++ exception handling, but I need to know how to apply the mechanism for use in my programs.

Technique

The C++ language Standard defines a standardized way of handling program anomalies at runtime. Such anomalies occur if your application attempts to acquire memory that is unavailable, tries to open a file that does not exist, or a divide-by-zero error occurs. By using the exception handling mechanism, your application can gracefully recover from errors.

In this How-To, you will create a program that will handle a number of exception conditions. In addition, the program presented here will demonstrate how write functions that throw exceptions.

Steps

1.  Change to your base source directory and create a new subdirectory named EXCEPT.
2.  Fire up your source code editor and type in the following code into a file named EXCEPT.CPP:
// except.cpp - program to demonstrate the
// use of exception handling in C++
#include <iostream>
#include <new>
#include <fstream>
#include <string>
using namespace std ;

static void acquireMemory( int elements ) ;
static void calculate( int value ) throw (int) ;
static void noThrow( void ) throw ( ) ;

const int MAX_ITERATIONS = 20 ;
const int MAX_ELEMENTS = 30000 ;

struct LargeStruct
{
    double bigd1[ MAX_ELEMENTS ] ;
    double bigd2[ MAX_ELEMENTS ] ;
    double bigd3[ MAX_ELEMENTS ] ;
    double bigd4[ MAX_ELEMENTS ] ;
}

 ;int errorCode = 0 ;

int main()
{
    int numerator = 10 ;
    int divisor = 0 ;
    int result = 0 ;

    try
    {
        result = numerator / divisor ;
        cout << “\nExpression succeeded!” << endl ;
    }
    catch( ... )
    {
        cout << “\nDivide-by-zero exception!” << endl ;
    }

    try
    {
        for( divisor = 10; divisor >= 0; divisor-- )
        {
            result = numerator / divisor ;
            cout << numerator << ‘/’ << divisor ;
            cout << “ == “ << result << endl ;
        }
    }
    catch( ... )
    {
        cout << “for() divide-by-zero exception!” << endl ;
    }
    try
    {
        acquireMemory( 30000 ) ;
    }
    catch( string s )
    {
        cout << s << endl ;
    }
    catch( ... )
    {
        cout << “Exception thrown for “ ;
        cout << “acquireMemory()” << endl ;
    }
    try
    {
       for( int i = 1; i >= 0; i-- )
        {
            calculate( i ) ;
            cout << “calculate(“ << i ;
            cout << “) succeeded” << endl ;
        }
    }
    catch( int ec )
    {
        cout << “exception for calculate()” << endl ;
    }

    return( 0 ) ;
}

void acquireMemory( int elements )
{
    long cnt = elements * MAX_ELEMENTS ;
    LargeStruct *s = (LargeStruct *)0 ;

    try
    {
        s = new LargeStruct[ cnt ] ;
    }
    catch( bad_alloc e )
    {
        cout << “Caught bad_alloc” << endl ;
    }
    catch( ... )
    {
        cout << “ allocation exception “ << endl ;
        throw ;
    }

    if( s == (LargeStruct *)0 )
        throw string( “s is null in acquireMemory” ) ;
    else
        delete [] s ;
}

void calculate( int value )
{
    if( value == 0 )
    {
        errorCode = 1 ;
        throw errorCode ;
    }
}
3.  Save the file and return to the command line.
4.  Run your compiler and linker on EXCEPT.CPP.
5.  The output should appear as follows:
Divide-by-zero exception!
10/10 == 1
10/9 == 1
10/8 == 1
10/7 == 1
10/6 == 1
10/5 == 2
10/4 == 2
10/3 == 3
10/2 == 5
10/1 == 10
for() divide-by-zero exception!
s is null in acquireMemory
calculate(1) succeeded
exception for calculate()

How It Works

You begin your journey with four preprocessor directives at the top of the source file:

#include <iostream>
#include <new>
#include <fstream>
#include <string>

The header file new contains a declaration for the standard exception class bad_alloc. The class bad_alloc is derived from the exception handling class exception. You must include new to use the functionality of bad_alloc.

After the namespace using directive, three functions are declared. These functions will be called by the main function. The second function declaration

static void calculate( int value ) throw (int) ;

contains an exception specification as part of its declaration. An exception specification is specified using the keyword throw, followed by a list of types within enclosing parentheses. An exception specification identifies the types of exceptions that a function will throw. The function declaration for calculate specifies that it will throw an int and only an int.

The last function declaration

static void noThrow( void ) throw ( ) ;

states that the function noThrow is guaranteed not to throw any exceptions; hence the empty specification list. By the way, noThrow is not defined in the program; this declaration only serves as an example of an empty exception specification.

Two constants are defined following the function declarations. These are merely used to specify array dimensions.

Next, a struct named LargeStruct is declared, encapsulating four attributes. Note that this struct is rather large (and purposefully so). I want to demonstrate the behavior of an application that fails to allocate memory.

The next definition, errorCode, is an integer that will be used as an argument to a throw statement.


Previous Table of Contents Next


Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home

Use of this site is subject to certain Terms & Conditions, Copyright © 1996-1999 EarthWeb Inc.
All rights reserved. Reproduction whole or in part in any form or medium without express written permision of EarthWeb is prohibited.