Sign in to follow this  

Manual construction and destruction

This topic is 1896 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

You have a pretty severe exception handling problem if any of the constructors throws inside constructAdditions(): you don't destroy any objects previously constructed in the function, which means that you'll be treating fully constructed objects as uninitialized memory in subsequent use of the class. Edit: and now that I think about it, you also need to reconstruct the objects you destroyed. Better do all the construction first and then destroy objects. Edited by SiCrane

Share this post


Link to post
Share on other sites
Thanks for the heads up - moveElements() would have the same problem.

What's the best way to handle it, conceptually? I could catch the exception, <handle it>, then rethrow the exception.
The problem is, the entire class assumes everything within 'bounds' is constructed. I can't have one or two elements sporadically not constructed in the middle of constructed elements.
One option would be destructing anything constructed thus far, then freeing the memory, resetting bounds to zero, and basically resetting the Grid container to it's initial default-constructed state.
Another option would be just ensuring that that last failed call to Resize() is rolled back, but to preserve the state of everything up to that point.

It seems the potential problems are:
1) [b]ensureCapacity[/b]() failing its memory allocation and throwing std::bad_alloc.
2) [b]moveElements[/b]() ([size=2]called by [b]ensureCapacity[/b]()[/size]) failing to move-construct the new elements, or destruct the old elements.
3) [b]constructAdditions[/b]() failing to construct or destruct elements being added or removed.

For problem '[b]1[/b]', I could free all memory, reset Grid to it's initialization state, and throw my own std::bad_alloc with error message.
For problem '[b]2[/b]' and 'problem '[b]3[/b]', it seems like just rolling back the last Resize() (by destructing and freeing), and then rethrowing the exception I caught, would be a preferable solution.

Is there a better or more common method?

Share this post


Link to post
Share on other sites
I think this covers it - any exception should roll back the Resize(), properly deconstructing any elements constructed.

[[url="http://pastebin.com/sx5e7vfC"]the entire code[/url]]
[[url="http://pastebin.com/VRQ2YwYp"]just the relevant parts[/url]]

Did I make a mistake anywhere?

The code seems less straight-forward than before, but I guess that's what I get when I mess with manual allocation and deallocation. [img]http://public.gamedev.net//public/style_emoticons/default/laugh.png[/img]

Share this post


Link to post
Share on other sites
Your moveElements() function doesn't look right. When an exception occurs in the constructors and destroying elements, only the last row show go up to lastColumn, all the previous rows should go to columns. The way you've coded it looks like it misses destroying elements at the end of previous rows.

Share this post


Link to post
Share on other sites
Also if reallocateMemory() is called with an empty newCapacity, it frees memory without destroying objects first.

Share this post


Link to post
Share on other sites
Excellent, fixed that, and simplified the for-loops.
[[url="http://pastebin.com/rJv7PVxm"]latest version[/url]] ([size=2]If anyone wants to use the code, for whatever reason, it's public domain - slap your own name on it and use it in your code[/size])

Thank you for all the help, everyone!
Any other mistakes in it I'll find through practical usage in my code.

Here's some [url="http://pastebin.com/gdiqvGmm"]example usage code[/url].

Share this post


Link to post
Share on other sites
If that's your latest code then you also seem to have a rule of three violation: I don't see either a copy constructor or an assignment operator. And since you're using C++11's rvalue references you might also want to add a move constructor and move assignment operator. A nothrow swap function might also be a good idea.

Share this post


Link to post
Share on other sites
Thanks, I usually don't manually handle memory, so I often forget the rule of three.

Here's how I'm implementing it:
[[url="http://pastebin.com/b3eLsbeZ"]relevant parts[/url]] [[url="http://pastebin.com/rJv7PVxm"]entire code[/url]]

Doing a few tests, I counted the number of destructions, constructions, moves, and copies, and the numbers balance out.

Share this post


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