• 10
• 12
• 12
• 14
• 16

# Catching STL Exceptions

This topic is 4674 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Just a quick question, should I catch a bad_alloc exception that an std::list might throw when adding an item to it? Also, is this the only exception that can be thrown by a list? Cheers

##### Share on other sites
it may be a little annoying check every time you insert into a list, but if you think its warranted, start here:
try {    // do stuff} catch(std::exception const& e) {   // do stuff with the exception}
and MSDN has a good series of articles on this.

##### Share on other sites
Lets get one thing straight standard library containers & algorithms *typically* don't throw exceptions but your user-defined types might and can, the default allocator type std::allocator uses the throw version of global operator new. In the case of your user-defined type's constructor throwing exceptions *typically* its caught, resources are released and the exception is rethrown to inform you.

Quote:
 Original post by Wavarianis this the only exception that can be thrown by a list?

if your user-defined types don't throw any exceptions then yes its the only possible one for std::list

##### Share on other sites
Thanks for the help - ratings have been given.

It's just that I have two lists, and if an item is successfully inserted into the first list, but not into the other (due to such an exception), then it makes sense for me to remove the item from the first list before rethrowing the exception.

All is well =)

##### Share on other sites
Just a warning, trying to keep two containers (lists in your case) "in sync" is usually a maintenance nightmare and a "smell" that something is wrong with the code design - however, suggesting an appropriate fix would require more knowledge of exactly what you're trying to do.

As for std::bad_alloc(), I would suggest that chances are you're completely screwed anyway (or damn near) if that ever gets thrown, because you're out of memory - might be better at that point to just save what data you can and let your program get the hell out of Dodge.

##### Share on other sites
Quote:
 Original post by ZahlmanJust a warning, trying to keep two containers (lists in your case) "in sync" is usually a maintenance nightmare and a "smell" that something is wrong with the code design - however, suggesting an appropriate fix would require more knowledge of exactly what you're trying to do.

Just as a general example, it's probably better to do something like this:
std::list< std::pair< int, Object* > > g_ObjectIndices;g_ObjectIndices.insert(std::make_pair(1, &MyObj));std::pair< int, Object* >& TempPair = *g_ObjectIndices.front();if(TempPair.first == SomeIndex) Use(TempPair.second);

This is by no means the only way to do it, but should give you some idea of how you can keep "two lists" "synced" using just one list.

##### Share on other sites
Yeah I figured the same in the end.

But don't worry about my design - in my posts, I try to give very simple and clear examples in order to get the answer I'm looking for. So don't look any deeper than you need to =D

EDIT: Well I might has well mention what I'm doing. I have two classes, kind of like a service / consumer or an event source / listener. Each class has a list, ie a service has a list of subscribed consumers, and a consumer has a list of active services.

When a consumer "dies", it needs to tell the service not to try calling it anymore, and thus removes itself from the service's list. The same happens vice-versa.

I figured that if I was attaching a consumer object to a service object, then if the service managed to add itself to the consumer's list, but the consumer was unable to be added to the service's list, then once the service dies, the consumer would be trying to access the invalid service pointer when it is being destroyed.

##### Share on other sites
Trying to handle std::bad_alloc exceptions is a bad idea (to do anything other than report an error that is).

To effectivley recover from a bad_alloc the very least you have to do is somehow remember what it is you were trying to construct, then free some memory, then try to construct again. Then repeat until you successfully allocate.

A much better way is to use a new handler function as new handlers take care of most of the above automatically.

##### Share on other sites
Handling std::bad_alloc doesn't necesssarily mean trying to make it succeed. A catch block for std::bad_alloc may do other things like back out of database transactions or transmit error signals over a network connection. Basically whenever you have a set of operations that should be collectively atomic, but multiple operations may throw an exception, then handling exceptions like std::bad_alloc is appropriate,

##### Share on other sites
Quote:
 Original post by SiCraneHandling std::bad_alloc doesn't necesssarily mean trying to make it succeed. A catch block for std::bad_alloc may do other things like back out of database transactions or transmit error signals over a network connection. Basically whenever you have a set of operations that should be collectively atomic, but multiple operations may throw an exception, then handling exceptions like std::bad_alloc is appropriate,

Point taken.

I should have been a bit more specific in my post.