Handling exceptions in stl containers.

Started by
3 comments, last by Ryan_001 11 years, 6 months ago
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?
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.
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?
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.
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.

This topic is closed to new replies.

Advertisement