28 Feb, 2010, BrainFRZ wrote in the 1st comment:
Votes: 0
The topic/description pretty much says it all. I'd like to know if there's a way of trying an array declaration in C++, and catching it if there wasn't enough RAM, rather than it just crashing.

Thanks!
28 Feb, 2010, Runter wrote in the 2nd comment:
Votes: 0
BrainFRZ said:
The topic/description pretty much says it all. I'd like to know if there's a way of trying an array declaration in C++, and catching it if there wasn't enough RAM, rather than it just crashing.

Thanks!


Yes, if you allocate it with malloc it will return null if it fails.

int *arr = (int *) malloc(sizeof(int) * 10); // array of length 10
if (!arr) { // Failed

}


It's possible that

int arr[1999999999];
if (!arr)
;


also does the same thing when on the stack. I just don't know for sure. Something to test? :)
28 Feb, 2010, Tyche wrote in the 3rd comment:
Votes: 0
try
{
a = new char[10];
}
catch (…)
{
cout << "I'm screwed?" << endl;
}
28 Feb, 2010, David Haley wrote in the 4th comment:
Votes: 0
As Tyche seems to be saying, while you can catch it it's unclear what you're going to do about it unless you can delete random bits of memory (in which case you probably should have deleted those as soon as it became possible to do so). The situation is different if you have some kind of garbage collection system running, where you can attempt to run the GC when you have no memory left to see if that frees something, but I would imagine that that is not the case here.
28 Feb, 2010, Runter wrote in the 5th comment:
Votes: 0
David Haley said:
As Tyche seems to be saying, while you can catch it it's unclear what you're going to do about it unless you can delete random bits of memory (in which case you probably should have deleted those as soon as it became possible to do so). The situation is different if you have some kind of garbage collection system running, where you can attempt to run the GC when you have no memory left to see if that frees something, but I would imagine that that is not the case here.


If it's attached to something that can be aborted without wrecking your application there's a very clear course of action. Report it failed and abort that segment of code. For example, a particular command in your MUD that you're concerned might have temporary memory issues, etc.
01 Mar, 2010, BrainFRZ wrote in the 6th comment:
Votes: 0
Well, what I was hoping was to do something like:
int foo;
try {
foo = new int[1000000]; // 4gig RAM
} catch( OutOfMemoryException e ) {
foo = new int[250000]; // 1gig RAM
}


Obviously, this is a ridiculous example, but that's just because it IS an example. :P The concept is that you aren't sure there's enough RAM on the computer to hold something, you then have it hold something less, and use a file or something. It wouldn't be an int[], but, as I said, the concept is the same. I just am unsure if there's an exception that does this. Or would "…" work?
01 Mar, 2010, David Haley wrote in the 7th comment:
Votes: 0
catch(…) will usually work, unless the 'new' implementation is somewhat old and only returns NULL. Also, std::bad_alloc is better than a blanket "…".

But you should realize that the memory you're dealing with here isn't just RAM: it's the entire virtual memory space of your program. On 32 bit systems, that is typically about 4GB. On 64 bit systems, it's more than you are likely to need in the near future. (To be more precise, it's about 2^64 = 18,446,744,073,709,551,616 bytes or 18,446,744 TB)

Generally when I see people worrying about something like this, I admit to getting a little suspicious if they're doing the right thing in the first place. You might be trying to work around some kind of bug in your code (which Runter alluded to). There are cases where you might prefer to store something in memory when possible, and hope that it doesn't get swapped out to disk, but if there isn't much memory left (in the virtual memory space – which can include disk space) you would write it out to a file.

For example, if it's ok for your stuff to be in a file, then you might as well just put it in that file from the get-go unless it's really important that it be in memory. But even then you need to realize that you can run out of RAM far before you run out of memory, so this trick is not at all guaranteeing that you're allocating into RAM.

EDIT: besides, the OS can typically come in and swap out your memory whenever it feels like it.
EDIT EDIT: hmm, Caius ninja'd one of my edits.
01 Mar, 2010, Caius wrote in the 8th comment:
Votes: 0
Operator new does not return 0 on failure, except on older and/or crappy compilers that aren't compliant with the C++ standard. Instead it throws a std::bad_alloc exception. Also, you should always catch exceptions by reference rather than by value:

catch( const std::bad_alloc &ex )
0.0/8