• Advertisement
Sign in to follow this  

Handling exceptions in stl containers.

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've been working on a hash container that is sort of a cross between unordered_set and a vector. Its uses open addressing/closed hashing and stores values in continuous memory, expanding like a vector as the load factor gets too high. In order to learn/become a better programmer I've tried to write this container as if it was an stl container, with all the bells, whistles and restrictions. I've been having a problem when it comes to exception safety. In order to support const types in the container, I need to write my own swap/move/copy functions in terms of copy construct and destruct. So to swap two pointers I came up with this:

UVTEMPLATE void UVBASE::swap_values (pointer p0, pointer p1) {

value_type t(move(*p0));

allocator.destroy(p0);
try { allocator.construct(p0,move(*p1)); }
catch (...) { allocator.construct(p0,sentinel()); throw; }

allocator.destroy(p1);
try { allocator.construct(p1,move(t)); }
catch (...) { allocator.construct(p1,sentinel()); throw; }
}


I think that should work (though TBH I haven't had the chance to compile/test it) but the judicious use of try/catch blocks has me worried about performance. How do normal stl containers handle this? For example:

vector<const int> v;
v.push_back(2);
v.push_back(8);
v.insert(v.begin(),10);
cout << "v[0] = " << v[0] << endl;


works fine, compiles and runs as expected. How do they handle the situation where a copy constructor throws an exception when moving/copying/swapping items around? Edited by Ryan_001

Share this post


Link to post
Share on other sites
Advertisement
My implementation doesn't (VS 2012). It will throw std::bad_alloc but doesn't deal with it internally which makes sense to me. std:: is so generic it'd be hard to really deal with an exception in any meaningful way.

Share this post


Link to post
Share on other sites
Weird, I'm using VS2012 as well, and the above snippet of code worked fine. Someone else said it doesn't work in gcc. Maybe I'm being unclear. The general problem is still, if all I can assume for a type is that its copy constructable, which means I can't use assignment, then all moves/copies/swaps have to be written in terms of allocator.construct() and alloctor.destroy() right? Which still brings us back to the exception problem. Perhaps I am incorrect in my assumptions? Is there another way to go about this that I'm unaware of?

Share this post


Link to post
Share on other sites
Take a look at xmemory and xmemory0 if you want to see how std containers manage it in VS2012. They will throw bad_alloc if there is one (note the absence of a "throw()" on push_back), there is no error handling within the container itself.

Share this post


Link to post
Share on other sites
Thank-you green that helped. It seems they are just doing what I expected and surrounding memory ops with try/catch. Maybe its not a big deal performance-wise.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement