Trying to test for catching of bad_alloc

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
int main()
{
    while(1)
        {
            myint * mynum;
            try {
                    if (!(mynum = new myint[num_of_elements]))
                        throw 1;
                }
            catch(bad_alloc&)
                {
                    printf("bad_alloc exception handled.\n");
                    break;
                }
            catch (exception &e)
                {
                    printf("Exception handled.\n");
                    break;
                }
            catch(...)
                {
                    printf("default exception.\n");
                    break;
                }
        }
    return 0;
}


It never throws or catches anything. It just eats up loads of memory and causes my system to crash.

Whats happening?
I'm following advice from http://www.cplusplus.com/doc/tutorial/exceptions/
I seem to be catching that exception just fine..
What exactly does "causes my system to crash" mean?
closed account (zb0S216C)
new doesn't return NULL/nullptr on a failed allocation. To make new return NULL/nullptr, write new as:
new( std::nothrow ) int( 10 ).

Also, if the allocation fails, and you haven't written the latter, an integer is thrown (you've explicitly thrown an int). As a result, catch( ... ) will always handle exception since you haven't provided an handler for int. If new does in fact fail, an exception is throw, therefore, throw 1 is redundant.

Where's your delete[] call? You allocate memory with every pass of the loop (which lasts forever and one when an exception isn't thrown), which is bad. However, you never call delete[] on the resource you allocated. Really, your code should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int *MyNumber( nullptr );

while( true )
{
    try
    {
        MyNum = ( new int[10] ); // Or whatever value.
    }

    catch( std::bad_alloc )
    {
        std::cout << "Bad allocation" << std::endl;

        // No need to call delete[] since the allocation failed. Loop again and try
        // to allocate the memory again.
        continue;
    }

    // The allocation succeeded. No need to loop again.
    break;
}

// Continue with main( ). 


Wazzak
Last edited on
@hamsterman it just means the system has no memory so everything gets bogged down so I cant do anything until my program crashes, which frees up more memory so I can do stuff again.

@Framework well i tried that too but the exception was never thrown.
and I don't delete mynum because I am trying to force the exception to be called.
closed account (zb0S216C)
wtf wrote:
well i tried that too but the exception was never thrown. (sic)

Then the allocation never failed, leaving you with allocated memory, which you never release.

wtf wrote:
I don't delete mynum because I am trying to force the exception to be called. (sic)

Bad idea to use a loop as it causes major memory leaks; you know this already. Try this method: http://www.cplusplus.com/reference/std/new/bad_alloc/

Why're you trying to cause a std::bad_alloc exception anyway?

Wazzak
I was just trying to test the darn thing. I'm learning exceptions now.

Why wouldn't I want to cause a bad_alloc?
And when I run out of memory, shouldn't that cause the std::bad_alloc to be thrown when I try to allocate more memory?
closed account (zb0S216C)
wtf wrote:
Why wouldn't I want to cause a bad_alloc? (sic)

All exceptions are the same. What exactly would you learn from all of this?

wtf wrote:
And when I run out of memory, shouldn't that cause the std::bad_alloc to be thrown when I try to allocate more memory? (sic)

If it fails, yes.

This code sample tells you how much memory you're allocating with each pass:
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
int main( ) 
{
    int *Pointer( nullptr );
    int SizeAllocated( 0 );

    while( true )
    {
        try
        {
            Pointer = ( new int[2] );
        }

        catch( std::bad_alloc )
        {
            std::cout << "Allocation failed" << std::endl;
            break;
        }

        SizeAllocated += ( 2 * sizeof( int ) );
        std::cout << SizeAllocated << std::endl;
        continue;
    }

    if( Pointer != nullptr )
        delete [] Pointer;

    return 0;
}

Just watch those bytes fly up.

Wazzak
Last edited on
let me rephrase, or clarify.
I don't actually know that that exception is not being caught, but "Allocation failed" is never being couted to my screen. Could be because like i said my system is crashing, and there weren't enough system resources or whatever is necessary to cout 1 line, but i certainly ran out of memory.
closed account (zb0S216C)
wtf wrote:
"Allocation failed" is never being couted to my screen. (sic)
"Allocation failed" will only appear on the screen if the allocation fails. If it doesn't appear on the screen, the allocation succeeds.

What OS are you using? Windows 7 (what I'm using) has a built-in memory leak detection system, so I can't give myself a memory leak on my machine.

Wazzak
Last edited on
I remember hearing that not all systems will throw a bad_alloc (or give any other measurable error condition) on failure to allocate memory. Perhaps this is one of those instances.

Don't remember where I heard that or how reliable it is, though.
I get the code as orig posted to throw a bad_alloc with

size_t num_of_elements = 512 * 1024 * 1024;

but not

size_t num_of_elements = 256 * 1024 * 1024;

On the first new, that is. I didn't look any deeper.

If you allocating just a single int inside the bigint class, as you were in other posts, it could take a long time to reach this point.

For your experiment, you could modify bigint to be greedier?

bad_alloc exception handled.
Press any key to continue . . .

Last edited on
Well it does appear to be strange what happens. when my computer freezes (on executing the 'memory fork bomb'), i'll try to close my program immediately, and then after about 30 seconds it will close, and then another 30seconds to a min before my computer beings to behave normally. I noticed in task manager my memory going from maxed out at 1.99GB down to near 0, then slowly growing back up to about 450mb, which is what it was at before I started my program. And I'm on windows 7. so maybe thats it.
I'm wondering if the strange behaviour is because you are allocating loads and loads of tiny little blocks of memory when the constructors of the objects in your original array of bigints are called.

Are you still allocating just a single extra int for each bigint?
this is my entire 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
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
#include <exception>
#include <stdio.h>

using namespace std;

class myint{public:int * d; myint(){d = new int[1];}~myint(){delete [] d;}};

const int num_of_elements = 10000;

int main()
{
    while(1)
        {
            myint * mynum;
            try {
                    if (!(mynum = new myint[num_of_elements]))
                        throw 1;

                }
            catch (bad_alloc& ba)
                {
                    cerr << "bad_alloc caught: " << ba.what() << endl;
                }

            //catch(bad_alloc&)
                //{
                  //  printf("bad_alloc exception handled.\n");
                    //break;
                //}//
            catch (exception &e)
                {
                    printf("Exception handled.\n");
                    break;
                }
            catch(...)
                {
                    printf("default exception.\n");
                    break;
                }
            //delete [] mynum;
        }
    return 0;
}
Topic archived. No new replies allowed.