Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RAII can not really guarantee to prevent resource leak, can it?

Pardon me if this question is too silly. The most common example of usefulness of using RAII is :

void func(){
  // create some object pointer using any smart pointer
  // do some operation that may throw

  return;
}
// whether method returns from the *return* statement or because of any exception it is guaranteed that the memory will be released

This article says that (if I understood correctly), if runtime system knows that there is no exception handler that can catch an exception after being thrown it may skip calling the destructors of automatic objects.

There is also a proposed solution to that problem, namely use catch(..) in main.

Now my concern is if the proposed solution is not used, then there may be resource leak even after using RAII. And there are situation when the solution can not be applied ( like creating a library which will be used by others). In that case serious problem can occur like corrupting a file that contains valuable information.

Should we really be concerned about the problem? Or I am just missing something?

like image 759
Rakib Avatar asked May 08 '14 15:05

Rakib


2 Answers

In order for your concern to be valid, you need some kind of resource which could be cleaned up by RAII, but which the OS won't clean up when std::terminate is called and your process dies.

So, let's examine the sort of resources you could reasonably use RAII to clean up:

  1. process-local memory: the OS will clean this up
  2. open files: the OS will close them, and flush anything already written, but any commit/finalize style operations you left to the RAII dtor won't happen
  3. open sockets: the OS will close them, but if your RAII dtor was supposed to send a friendly logout/goodbye, that won't happen
  4. shared memory: again, OS-level resources will be released but any explicit cleanup or consistency code won't be executed
  5. etc. (especially, Alf suggested some more externally-visible resources I hadn't thought of)

So the issue isn't generally with resources, which will generally be released by the OS, but semantics, where your RAII dtor was supposed to guarantee some clean state of a shared resource (shared memory, or files, or a network stream).

Should we really be concerned about the problem?

Well, we should be concerned about correct program semantics anyway. If your program has some external side-effects you need to guarantee, then a catch-all (at least around the relevant code) to guarantee RAII cleanup is the simplest of your concerns.

like image 54
Useless Avatar answered Sep 23 '22 23:09

Useless


I'm assuming here that you are not so much concerned about things such a memory leaks, but more about data corruption.

You'll need to analyze your design and application carefully, but I suppose it is theoretically possible that you might want a "last-chance" type of failsafe that would kick-in in the case of a serious program bug that would cause an uncaught exception. In which case, you could replace std::terminate.

That said, if you are truly concerned about file corruption, what you describe would be inadequate. The way to prevent file corruption is by careful ordering of operations such as read/writes and proper flushing of file buffers (using fsync or fdatasync on Linux, for example) before considering an operation to be complete (i.e., committing an operation).

like image 30
kec Avatar answered Sep 24 '22 23:09

kec