Title
Matching deallocation for uncaught exception
Status
open
Section
7.6.2.8 [expr.new]
Submitter
Jim X

Created on 2022-04-13.00:00:00 last changed 7 months ago

Messages

Date: 2022-04-13.15:49:58

Suggested resolution:

Integrate freeing dynamically-allocated memory with stack unwinding (14.3 [except.ctor]), since this is what implementations actually do.

Date: 2022-04-13.00:00:00

Initialization of an object may terminate via an exception, in which case any dynamically-allocated memory is freed, per 7.6.2.8 [expr.new] paragraph 26:

If any part of the object initialization described above [ Footnote: ... ] terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called to free the memory in which the object was being constructed, after which the exception continues to propagate in the context of the new-expression. If no unambiguous matching deallocation function can be found, propagating the exception does not cause the object's memory to be freed.

However, implementations do not consistently support this provision in case the exception remains uncaught:

  #include <iostream>
  struct C {
    void* operator new(std::size_t n) {
      std::cout << "malloc\n";
      return malloc(n);
    }
    void operator delete(void* ptr) {
      std::cout << "free\n";
      free(ptr);
    }
    C() {
      throw 0;
    }
  };
  int main() {
    auto ptr = new C;
  }

Both clang and GCC do not free the memory in this example; they do so if the exception is caught in main.

Maybe a similar provision as used for stack unwinding in 14.4 [except.handle] paragraph 9 is desirable:

If no matching handler is found, the function std::terminate is invoked; whether or not the stack is unwound before this invocation of std::terminate is implementation-defined (14.6.2 [except.terminate]).
History
Date User Action Args
2022-04-13 15:49:58adminsetmessages: + msg6795
2022-04-13 00:00:00admincreate