Hello all,
Please suppose I have a function that accepts a pointer as a parameter. This function can throw an exception, as it uses std::vector<>::push_back()
to manage the lifecycle of this pointer. If I declare it like this:
void manage(T *ptr);
and call it like this:
manage(new T());
if it throws an exception pushing the pointer into the std::vector<>
, I effectively have got a memory leak, haven't I?
Would declaring the function like this:
void manage(std::auto_ptr<T> ptr);
solve my problem?
I would expect it to first allocate the std::auto_ptr
on the stack (something that I guess couldn't ever throw an exception) and let it acquire ownership over the pointer. Safe.
Then, inside the function, I would push the raw pointer into the std::vector<>
, which is also safe: if this fails, the pointer will not be added, but the smart pointer will still be owning the pointer so it will be destroyed. If the pushing succeeds, I would remove the smart pointer's ownership over that pointer and return: this can't throw an exception, so it will always be fine.
Are my theories correct?
-- Edit --
No, I think I can't do that. Doing that would require taking a non-const reference to rvalue (to take away ownership from the smart pointer). I would have to write
std::auto_ptr<T> ptr(new T());
manage(ptr);
for that to work, something that's quite inconvient in my case. I'm writing this so that I can implement RAII without polluting much the code. Doing that thing would not help, then. That would be catch 22.
-- Edit 2 --
Pulling what Jason Orendorff said down there here for quick reference by readers, the ultimate solution seems to be the following:
void manage(T *ptr)
{
std::auto_ptr<T> autoPtr(ptr);
vector.push_back(ptr);
autoPtr.release();
}
This solves the problem of the useless non-const reference to rvalue.
When I finish this class I'm coding I'll post it back here in case anyone finds it useful.
-- Edit 3 --
Ok, there has been a lot of discussion here, and there are key points that I should have clarified before. In general, when I post at stackoverflow, I try to explain the reason behind my questions and, in general, that is completely useless. So this time I thought I should go straight to the point. Turns out it didn't work quite well XD
Unfortunately my brain is deadlocking now, so I think I won't even be able to explain correctly what I first thought to accomplish my goals. I am trying to find a good solution for atomic operations and exception-safe code writing that fits lots of cases, but really, I can't handle it XD I think this is the kind of thing I will only master with time.
I am a really new C++ programmer and my focus is game development. When an exception is thrown in a game engine, it is the end of execution. The system will free all the memory for my process, so it doesn't really matter if one or two pointers leak here and there. Now that I am developing a server application, I'm finding it hard to deal with exceptions, because an exception can't crash the server; it must "crash the request".
That is, "Well, client, unfortunately the developers didn't foresee this condition, so you'll have to try it later (up to here, it is basically the same thing as with a game engine, nothing is being repared, only it is isolated to the context of just a request, and not the whole process). But don't panic, as everything was left in a valid state (here is one of the differences, however. The process isn't terminated, so the operating system can't free the resources for you; furthermore, you have to pay attention to undo the operations so far, so that you don't lock completely an user's account, for example, or even a full service provided by the server).".
I will just code more and more and note down my problems so that I can write a better question next time. I wasn't prepared to ask this now, I'm really sorry.
Thanks a lot for your replies, I really like stackoverflow. It is absolutely amazing how fast my questions are answered and how enlightening your answers are. Thanks.