Jump to content

  • Log In with Google      Sign In   
  • Create Account

Handling exceptions in stl containers.


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 Ryan_001   Prime Members   -  Reputation: 1395

Like
0Likes
Like

Posted 19 October 2012 - 09:20 AM

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, 19 October 2012 - 09:28 AM.


Sponsor:

#2 greenvertex   Members   -  Reputation: 510

Like
0Likes
Like

Posted 19 October 2012 - 10:54 AM

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.

#3 Ryan_001   Prime Members   -  Reputation: 1395

Like
0Likes
Like

Posted 19 October 2012 - 11:09 AM

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?

#4 greenvertex   Members   -  Reputation: 510

Like
1Likes
Like

Posted 19 October 2012 - 11:27 AM

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.

#5 Ryan_001   Prime Members   -  Reputation: 1395

Like
0Likes
Like

Posted 19 October 2012 - 01:42 PM

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.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS