views:

59

answers:

3

I'm trying to figure out if the boost::multi_array constructor or resize method can throw a bad_alloc exception (or some other exception indicating the allocation or resize failed). I can't find this information in the documentation anywhere.

Clarification (added from comment):

This is a scientific algorithm that can fall back to a less memory intensive (slower) method if the allocation fails. Basically there are two dynamically allocated 3-dimensional arrays to hold "distances" (correlation) between all pairs of genes in a query and all genes in a cross-validation set for each of a large number of datasets. The slower method recalculates each distance on the fly as it is needed. This is for a C++ version of an existing Java implementation, which implemented both methods and would fall back on an out of memory exception. I don't really expect to run out of memory.

A: 

The absence of explicit exception-specification is intentional. See this sub-section for an explanation. Further, note that an absence of an explicit specification means that there is no restriction on the type of exception a function can throw. So, at the least, the ctor and the resize function can throw exceptions in case memory is exhausted or if an item-object copy fails.

Some generic references which inspired Boost which you may be interested in are:

dirkgently
I do not think OP meant he was searching for exception-specifications...
gimpf
@gimpf: No, but the lack of the same may have confused him.
dirkgently
May well be. I hope for clarification.
gimpf
+1  A: 

1st: (answering the real question): As it uses dynamically allocated memory, yes, it can throw std::bad_alloc (I have never seen boost translation std::bad_alloc exceptions; it would be crazy to do so).

2nd: (comment on your clarification): You do need the information of available physical memory to optimize the performance of your algorithm at run-time. However, you cannot rely on std::bad_alloc to determine how much memory you have available, as modern operating systems use such a thing as overcommit, meaning: they (almost) never return a failed allocation attempt, but instead just give you some "memory", which will only fail to jump into existence when you actually try to access it.

In Java this may work as the VM is doing many things for you: it tries to allocate some continuous memory chunks, and does so with respect to the available physical memory, and the available unused physical memory to decide whether it should stress the GC more or just allocate a larger junk. Also, for performance reason you need to take into account that virtual memory and physical memory are quite different concepts.

If you need to performance-optimize you algorithms for such cases (which may well be necessary, depending on your area of work), you need to inspect your platform-specific functions which can tell you how "the real world" looks like.

gimpf
see my comment above, the algorithm, as implemented by the original researcher in Java, supports two methods. A slower one is used if it is unable to allocate enough memory. I was looking to re-create this behavior for the C++ version, although I normally don't expect to run out of memory. We already got rid of this type of fall-back on another one of the algorithms used by the program when we found my C++ implementation was much more efficient in terms of memory than the older Java one.
Glen
A: 

Why not test it ? It's easy to pass an absurdly high value to generate the exception.

On the other hand, what do you plan on doing if does generate this exception ? std::bad_alloc is the kind of exception that you usually cannot deal with at micro level...

For example, on a webserver, you would typically perform some cleanup (rollback on db transaction ?) and then return a 500 error to the user.

But when memory is exhausted, there is no much you can do safely, since you have to tread carefully if you don't want to once again hit the memory wall that you know is close :)

Matthieu M.
this is a scientific algorithm that can fall back to a less memory intensive (slower) method if the allocation fails. Basically there are two dynamically allocated 3-dimensional arrays to hold "distances" (correlation) between all pairs of genes in a query and all genes in a cross-validation set for each of a large number of datasets. The slower method recalculates each distance on the fly as it is needed. This is for a C++ version of an existing Java implementation, which implemented both methods and would fall back on an out of memory exception. I don't really expect to run out of memory
Glen