set_new_handler function (called by new oper

Aris
2012-04-01
2012-09-26
  • Aris
    Aris
    2012-04-01

    This program allocates memory with new operator.
    When stack is out of memory and because i declare a function with
    set_new_handler new calls the declared function
    "new_exception_handler".

    One of the choices to return from the declared function is to free memory by
    deallocating memory.

    The first problem in the example program that i use here is that in set_new_handler(new_handler p)

    p must be type void(*)(void)
    that means that p function can't get any arguments.
    so i have to use global variables to be visible inside p function.

    has anyone any idea how can i make p function to see variables declared in
    main??

    The second choice to return from the declared function is to free memory by closing an application.
    But i have no idea how can i make new_exception_handler function to know
    that an application has been closed.

    Here is my example code:

    # include <cstdlib>
    
    #include <iostream>
    using std::cout;
    using std::cerr;
    
    #include <exception>
    using std::exception;
    
    #include <new>
    using std::bad_alloc;
    using std::set_new_handler;
    
    # define SIZE 5000
    # define ONE_MB 131072 // to a typical 32-bit system sizeof(double) * ONE_MB = 1Mb
    
    //global variables
    double *ptr[SIZE];
    int i;
    
    void new_exception_handler(void)
    {
       static char counter = 0;   
       cerr<< "\n\nSystem out of memory\nDeallocating memory\n";
    
       if(counter == 2)
          throw bad_alloc();
    
       for(register int j = 0; j < 5; j++, i--)
          delete[] ptr[i];
    
       i++;
       counter++;
    
       system("pause");   
       return;
    }
    
    int main(void)
    {
       set_new_handler(new_exception_handler);   
       cout << "\nnew_exception_handler set as new allocation failure handler\n";
    
       cout << "\nTo start memory allocation\n";
       system("pause");
    
       try
       {
          for(i = 0; i < SIZE; i++)
          {
             cout << "allocation\n";
             ptr[i] = new double[ONE_MB];
    
             cout << "Allocated 1MB that starts from memory address: " << (void*)ptr[i] << "\n";
          }
       }
       catch(exception &bad)
       {
          cout << "\nmemory error " << bad.what() << "\n";    
       }
    
       cout << "\n\n\t\tTo start memory deallocation\n";   
       system("pause");
    
       for(register int i = 0; i < SIZE; i++)
       {
          delete [] ptr[i];   
       }
    
       cout << "\n\n\t\t Normal main() termination\n\n";   
       system("pause");
    
       return 0;
    }
    
     
  • Jim Pattee
    Jim Pattee
    2012-04-05

    You are using the same pointer variable "ptr" for all of your allocations.
    Each allocation needs a separate variable.
    This should be fixed before you work on the other problems.

    You will probably have to free the memory in a "catch" statement since
    new_exception_handler doesn't allow arguments.
    It would be better if the "try" statement were inside the for loop.

     
  • Aris
    Aris
    2012-04-07

    Tks for your reply, but:

    I use the same ptr just because in this example i just want to get the system
    out of memory and make new throw a bad_alloc exception, so i don't care to
    have a handler for each allocation...

    your idea to put try - catch inside for() works but i want to handle
    exceptions outside the main path of the program, with a function which could
    be used as a global way of handling this kind of exceptions in my project.

     
  • Jim Pattee
    Jim Pattee
    2012-04-08

    You are deleting the same pointer 5 times with a "for" loop. That is not going
    to work. Why are you doing this? It needs to be fixed before you can test the
    rest.

    The new_exception_handler doesn't allow arguments. You cannot do it the way
    you are trying.

    You could have a try-catch in a separate function to allocate memory and
    handle the error in the same function. You could call the exception handling
    function from a "catch" statement and pass it the pointer. Or you could put
    the memory allocation pointers in a class variable and get them with a "get"
    statement. You need to think of solutions other than new_exception_handler.

     
  • Hmm, I don't get it :(