Exception Runtime_error : new operator with bad allocation

May 31, 2011 at 12:14pm
Hello everybody ,

I need to use exceptions for bad allocation of memory when I use files and pointers to files .
I must use the "runtime_error" class .

Given the following code for the exception:

I have a Base Class that somewhere within the code I have the following code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Class Base 
{
 

// code 

fstream *firstPtr;
fstream *secondPtr;


	try
	{
		firstPtr  = new fstream();
		secondPtr = new fstream();

		if (firstPtr  == ???)
			throw DbAllocationException("Allocation went wrong");

		if secondPtr == ???)
			throw DbAllocationException("Allocation went wrong");

	}


	catch (runtime_error& err)
	{
		cout << err.what() << endl;
	}

// some more code 

}


How can I use the mechanism of exceptions here ? since I cannot check an IF condition with NULL ,regarding try and catch :
1
2
if (firstPtr  == NULL)
   // throw exception 


Thanks a lot ,Dave
Last edited on May 31, 2011 at 1:56pm
May 31, 2011 at 12:26pm
You could check for the bad_alloc exception thrown by new, and then in the catch block throw your own exception as you want to.

Or you could allocate like so: firstPtr = new (std::nothrow) fstream();. Then new doesn't throw if there is an error, it returns a NULL pointer, which you can then check for :)
May 31, 2011 at 12:29pm
Well ,that's sounds nice . But if I check "if (firstPtr == NULL)" I get that the pointer is indeed
points to NULL , that's why that check ain't helpful.
How do I use the bad_alloc ?

thank you
Dave



EDIT :


One more thing :
1
2
3
this one : firstPtr = new (std::nothrow) fstream();

and that one : firstPtr = new fstream();

are the same ?
Last edited on May 31, 2011 at 12:31pm
May 31, 2011 at 12:42pm
are the same ?

No, not the same. They both allocate memory on the heap for an fstream. However, the first one returns a null pointer in the event of an error. The second throws an exception of type std::bad_alloc.

To do the bad_alloc thing, you catch an exception just as you do in your program:
1
2
3
4
5
6
7
try {
   firstPtr = new fstream();
}
catch (bad_alloc)
{
   // etc
}


However, if your firstPtr is null with the "nothrow" version then it means an allocation problem.

By the way, if you have used using namespace std (as you appear to have), you can of course just write (nothrow) rather than (std::nothrow).
Last edited on May 31, 2011 at 12:42pm
May 31, 2011 at 12:44pm
Oh, and I noticed two typos in your second code segment (in your original post). On line 1 you wrote Class not class and on line 19 you missed an opening bracket after if.
May 31, 2011 at 12:50pm
I've tested the following : (I have the 'using namespace std' at the top ,thanks ::))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
	try
	{
		firstPtr = new  fstream();
		if (firstPtr == NULL)
			throw DbAllocationException(ALLOCATION_ERROR);

	}

	catch (runtime_error& err)
	{
		cout << err.what() << endl;
	}

	try
	{
		secondPtr = new fstream();
		if (secondPtr  == NULL)
				throw DbAllocationException(ALLOCATION_ERROR);
	}

	catch (runtime_error& err)
	{
		cout << err.what() << endl;
	}


// remark : ALLOCATION_ERROR is a const string within my code  


this code compiled just fine , there were no catches and no errors .
My question is , do you think this is enough , or should I use the option above that you offered ?
Again,thanks

Dave
May 31, 2011 at 1:10pm
Unless you use (nothrow), these lines are pointless:
1
2
3
4
5
if (firstPtr == NULL)
			throw DbAllocationException(ALLOCATION_ERROR);

if (secondPtr  == NULL)
				throw DbAllocationException(ALLOCATION_ERROR);


If the allocation fails, an exception is thrown and these lines are skipped. If the allocation succeeds, the pointer will not be null.

Either exclude nothrow and catch bad_alloc or include throw and test for NULL.
Last edited on May 31, 2011 at 1:10pm
May 31, 2011 at 1:20pm
Oh sorry ,I didn't notice ,here is the complete code in my Base class :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
	try
	{
		firstPtr= new (nothrow) fstream();
		if (firstPtr == NULL)
			throw DbAllocationException(ALLOCATION_ERROR);

	}

	catch (runtime_error& err)
	{
		cout << err.what() << endl;
	}

	try
	{
		secondPtr= new (nothrow) fstream();
		if (secondPtr== NULL)
				throw DbAllocationException(ALLOCATION_ERROR);
	}

	catch (runtime_error& err)
	{
		cout << err.what() << endl;
	}

Last edited on May 31, 2011 at 1:20pm
May 31, 2011 at 1:45pm
Okay, but why do you have the try and catch blocks? What runtime_error are you expecting?
May 31, 2011 at 1:56pm
Well,nothing much,just my assignment's requirements.It demands validation for each usage
of new allocation (i.e. using new).thank you !
Last edited on May 31, 2011 at 1:57pm
May 31, 2011 at 2:01pm
Well as far as I am aware you either test for NULL and use (nothrow) or use try and catch blocks.


Of course, if your lecturer/whatever has told you differently, then it's probably best to complete the assignment as he/she wants ;)
Topic archived. No new replies allowed.