GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read
 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 30-Mar-2006, 16:36
David52 David52 is offline
New Member
 
Join Date: Mar 2006
Posts: 18
David52 is on a distinguished road

Memory Allocation Exceptions in C++


Hello, everybody.

I have some questions about exception catching for dynamic memory allocation in C++.

I have been using Microsoft’s Visual C++ version 6 for a number of years. When allocating memory dynamically, I have always done a check for new returning NULL. However, I believe the proper technique is to throw-catch an exception.

For the sake of learning this new technique, I have written a small program and posted it online.
Version 0 is an example using the old technique (Visual C++ version 6):

http://www3.telus.net/thothworks/mulmatvec0.html

Version 1 is a first attempt at coding with a try-catch block (note this version is written with Visual C+++ 2005; I upgraded recently):

http://www3.telus.net/thothworks/mulmatvec1.html

A few questions come to mind. How do you tell where the exception was thrown and how do you handle it?

Consider my posted code.
Say I want Matrix A to be a 1000 X 1000 array of type double, but assume the computer runs out of memory while trying to allocate space for column 750. Would the catch routine have to deallocate all space allocated up to the point that the exception was thrown (i.e. - deallocate space that was successfully allocated for columns 0 – 749, as well as all the rows)? Or if the exception occurs while trying to allocate space for 1D array b2, would I have to deallocate the space assigned to A and b1? Maybe I am wrong; this is new to me. So I have two questions:

1) IF an exception is thrown, does good coding practice require the catch routine to deallocate all space assigned up to that point before outputting an appropriate error message and exiting the program?

2) If the answer to question #1 is "yes", how do I indicate to the catch block exactly what caused the exception to be thrown so that I know exactly what memory assignments have to be deallocated?

Looking forward to your feedback.


David
  #2  
Old 30-Mar-2006, 16:53
David52 David52 is offline
New Member
 
Join Date: Mar 2006
Posts: 18
David52 is on a distinguished road

Re: Memory Allocation Exceptions in C++


Oops! Didn't see an indication that links would be disabled.

Here they are in plaintext, Version 0 and Version 1, respectively:

http://www3.telus.net/thothworks/mulmatvec0.html

http://www3.telus.net/thothworks/mulmatvec1.html


Regards,


David
  #3  
Old 30-Mar-2006, 18:58
davis
 
Posts: n/a

Re: Memory Allocation Exceptions in C++


Quote:
Originally Posted by David52
Hello, everybody.

I have some questions about exception catching for dynamic memory allocation in C++.

I have been using Microsoft’s Visual C++ version 6 for a number of years. When allocating memory dynamically, I have always done a check for new returning NULL. However, I believe the proper technique is to throw-catch an exception.

For the sake of learning this new technique, I have written a small program and posted it online.
Version 0 is an example using the old technique (Visual C++ version 6):

www3.telus.net

Version 1 is a first attempt at coding with a try-catch block (note this version is written with Visual C+++ 2005; I upgraded recently):

www3.telus.net

A few questions come to mind. How do you tell where the exception was thrown and how do you handle it?

Consider my posted code.
Say I want Matrix A to be a 1000 X 1000 array of type double, but assume the computer runs out of memory while trying to allocate space for column 750. Would the catch routine have to deallocate all space allocated up to the point that the exception was thrown (i.e. - deallocate space that was successfully allocated for columns 0 – 749, as well as all the rows)? Or if the exception occurs while trying to allocate space for 1D array b2, would I have to deallocate the space assigned to A and b1? Maybe I am wrong; this is new to me. So I have two questions:

1) IF an exception is thrown, does good coding practice require the catch routine to deallocate all space assigned up to that point before outputting an appropriate error message and exiting the program?

2) If the answer to question #1 is "yes", how do I indicate to the catch block exactly what caused the exception to be thrown so that I know exactly what memory assignments have to be deallocated?

Looking forward to your feedback.


David

Answer 1 is no. If new is unable to allocate the memory block, it won't "partially" allocate some portion of it, rather, it will just fail and throw an exception, which is why checking the return value of new for null is a waste of effort.

However, your code (posted in the links) isn't very representative of "real" C++. Rather it is very C-like that exploits some C++ capability. Ideally, you'd want to encapsulate your functionality into a class such that any deallocation necessary would be handled by a destructor.

If you have already allocated several memory regions using new and some later allocation fails, it would be appropriate to deallocate the previous allocations if possible.

Next time, you may just want to enclose your code in [c++] your code [/c++] tags rather than add remote links.


:davis:
  #4  
Old 31-Mar-2006, 14:07
David52 David52 is offline
New Member
 
Join Date: Mar 2006
Posts: 18
David52 is on a distinguished road

Re: Memory Allocation Exceptions in C++


Hi, Davis.

Thanks for the reply.

Quote:
Originally Posted by davis
Next time, you may just want to enclose your code in [c++] your code [/c++] tags rather than add remote links.

:davis:

I thought about that and, for small code snippets in the future, I will do that. However, I am planning to leave the page up, so thought it might be easier to refer to a single page rather than look for code snippets all over. Plus, I thought having line numbers might be convenient.

Quote:
Originally Posted by davis
Ideally, you'd want to encapsulate your functionality into a class such that any deallocation necessary would be handled by a destructor.

That will be the next version of the program; I am planning to write a Version 2 of the program using <vector> class.

Quote:
Originally Posted by davis
However, your code (posted in the links) isn't very representative of "real" C++. Rather it is very C-like that exploits some C++ capability.

True. I like keeping the code as close to plain old “C” as possible because I go back and forth between “C” and Javascript so often. Perhaps, once I write Version 2 of the program, I will write a version 3, which incorporates as many cutting-edge features as possible. I have seen a few books in which fancy class definitions are claimed to speed up code execution substantially. However, I feel that those codes have hidden the algorithm, whereas I actually want to present the algorithm clearly.

Quote:
Originally Posted by davis
If you have already allocated several memory regions using new and some later allocation fails, it would be appropriate to deallocate the previous allocations if possible.

Okay, just so I am crystal clear on this point. Let’s say I have the following code:

CPP / C++ / C Code:
try {  // Beginning of try block
    b1 = new double[mDim];
    A = new double*[mDim]; //Allocate space for pointers to rows of A matrix
    for (i = 0; i < mDim; i++) {
        A[i] = new double[mDim]; //Allocate space for columns of A matrix
    }//End for i
    b2 = new double[mDim];
    b3 = new double[mDim];
    b4 = new double[mDim];
    b5 = new double[mDim];
} // End of try block

catch (...) { // Catch block, for exceptions
    cout << "In catch block, so an allocation failed.\n";
    in.close();
    return 0;
} // End of catch block

Also, let’s say an exception occurs in the for loop when i = 750. Somehow I would have to tell the catch block to do the following:

CPP / C++ / C Code:
 
delete [] b1;
for (j = 749; j >= 0; j--)
   delete [] A[j];
delete [] A;

Or, if the exception occurred when allocating space for b5, I would have to tell the catch block to do the following:

CPP / C++ / C Code:
delete [] b1;  // Delete b1 array
for (j = mDim; j >= 0; j--)   // Delete ALL memory allocated to A matrix
   delete [] A[j];
delete [] A;
delete [] b2;  // Delete b2 array
delete [] b3;  // Delete b3 array
delete [] b4;  // Delete b4 array

This is the part that is tripping me up. How is the catch block told how much memory to deallocate? I suppose if all arrays were 1D, I could throw an integer exception to indicate which array caused the exception. However, the presence of a 2D array means I also need the ability to specify that an exception was thrown by the 2D array AND which column was being allocated at the time.

Regards,


David
  #5  
Old 31-Mar-2006, 16:58
ubergeek ubergeek is offline
Awaiting Email Confirmation
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough

Re: Memory Allocation Exceptions in C++


well, there are a couple of ways. you can throw your own struct or class as an exception, that can have as many data members as you want to keep track of where you were in the allocation. or, you can use wrapper classes instead of raw pointers; these would hold a raw pointer as a private data member, and use new on it in the destructor and delete in the destructor. you could have a get() function or operator overloads for * and ->. (Note that these classes exist already, in the STL and in Boost.) The wrapper class would delete itself when an exception was thrown, so you wouldn't have to worry about the memory management.
  #6  
Old 01-Apr-2006, 03:54
xslainx xslainx is offline
New Member
 
Join Date: Mar 2006
Posts: 10
xslainx is on a distinguished road

Re: Memory Allocation Exceptions in C++


Davis, If your concern is catching memory allocation exceptions? can you not malloc the space required

CPP / C++ / C Code:
        char *buf = NULL;
        char *dname = NULL;

        /* Dynamically assigns 32 times number of processes as buffer size */
        buf = (char *)vmalloc(32 * pid_task);

        /* A buffer of size 1024 for d_path to use */
        dname = (char *)vmalloc(1024);

        if(!buf || !dname) /* check if the buffers were properly created */
        printk( KERN_DEBUG "Memory allocation error\n");

        else { //DO REAL WORK.
this was something i had written recently for a kernel project, however the idea is the same. you want to catch the exception before you try to do anything with the memory area.

The kmalloc i believe is specific to kernel development libraries under linux, however it works very much like malloc.

cheerios
  #7  
Old 03-Apr-2006, 13:28
David52 David52 is offline
New Member
 
Join Date: Mar 2006
Posts: 18
David52 is on a distinguished road

Re: Memory Allocation Exceptions in C++


Quote:
Originally Posted by ubergeek
well, there are a couple of ways. you can throw your own struct or class as an exception, that can have as many data members as you want to keep track of where you were in the allocation.

Thanks, ubergeek.

I think this is the way I want to go for now; I don't want to use the STL or any fancy classes for the present program. I think a simple class would work; all it needs is two entries, one variable to indicate what variable's attempted allocation caused the exception and, if the exception was thrown while trying to allocate memory for the matrix, the second variable should indicate WHERE in the matrix the exception was thrown. (At least, that is how I THINK it should work; figuring out HOW to make it work is the problem.

Would you be able to post a code snippet, showing exactly how this would be done?

Regards,


David
  #8  
Old 03-Apr-2006, 13:44
ubergeek ubergeek is offline
Awaiting Email Confirmation
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough

Re: Memory Allocation Exceptions in C++


well, actually my explanation was a bit off; new throws a std::bad_alloc exception when it fails, so you'd have to do something like this:
CPP / C++ / C Code:
    //wherever A, b1, b2 etc are declared, initialize them to NULL
    int i = 0; //this is the variable that is used in the for loop (have it outside the try scope so that it can be accessed from the catch block)
try {  // Beginning of try block
    b1 = new double[mDim];
    A = new double*[mDim]; //Allocate space for pointers to rows of A matrix
    for (i = 0; i < mDim; i++) {
        A[i] = new double[mDim]; //Allocate space for columns of A matrix
    }//End for i
    b2 = new double[mDim];
    b3 = new double[mDim];
    b4 = new double[mDim];
    b5 = new double[mDim];
} // End of try block

catch (bad_alloc& except) { // Catch block, for allocation exceptions
    cerr << "In catch block, so an allocation failed because: " << except.what() << endl;
    if (b1) delete[] b1;
    if (A)
    {
         for (; i > 0; --i) //count down from the highest value of i that we reached before the exception
         {
               delete[] A[i];
         }
     delete[] A;
    }
    if (b2) delete[] b2;
    if (b3) delete[] b3;
    if (b4) delete[] b4;
    if (b5) delete[] b5;
    in.close();
    return 0;
} // End of catch block
  #9  
Old 04-Apr-2006, 14:02
David52 David52 is offline
New Member
 
Join Date: Mar 2006
Posts: 18
David52 is on a distinguished road

Re: Memory Allocation Exceptions in C++


Thanks, ubergeek.

(What is your name, by the way?)

Hopefully, I will find some time this weekend to work on the program, and incorporate your suggestions. (Coding is just a hobby for me, not a job.)

Haven't found time to research bad_alloc yet but, based on the context, it looks like it holds the memory location of the variable that was being allocated when the exception was thrown. Too bad it couldn't be converted to an integer somehow; then, by ordering the allocations and de-allocations appropriately, the catch block could use a switch statement instead of several if statements. I imagine this will get tedious as a program gets very big. Anyhow, I will play with the program this weekend.

Again, thanks. You have given me something to work with.


David
  #10  
Old 04-Apr-2006, 14:13
ubergeek ubergeek is offline
Awaiting Email Confirmation
 
Join Date: Jan 2005
Posts: 775
ubergeek is a jewel in the roughubergeek is a jewel in the roughubergeek is a jewel in the rough

Re: Memory Allocation Exceptions in C++


Glad I could help. The vector idea was already mentioned, but just to reiterate: it will make your exception handling much easier. Vectors allocate their elements on the heap, but destruct themselves automatically (as long as they are declared locally) when an exception is thrown.
--Alex
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic memory allocation of unknown/variable data length Radi0ShacK C++ Forum 18 14-Feb-2006 22:26
Memory allocation issue kobi_hikri C++ Forum 6 27-Oct-2005 12:16
Pointer Usage in C++: Beginner to Advanced varunhome C++ Forum 0 19-Aug-2005 09:25
[Tutorial] Pointers in C (Part I) Stack Overflow C Programming Language 1 08-Apr-2005 18:35
3D array dynamic memory allocation cjwatchdog C Programming Language 3 20-Feb-2004 16:27

Network Sites: GIDNetwork · GIDApp · GIDBlog · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 16:23.


vBulletin, Copyright © 2000 - 2014, Jelsoft Enterprises Ltd.