This might relate to bug 34158 comment #6.
When throwing an exception in the constructor of an object being allocated as a
result of a call to a (placement) new expression, the corresponding (placement)
operator delete does not get called - unless the new expression is placed
inside a try-catch block AND the exception being throw can be caught by the
catch block.
The expected output of the code below would be (the address' may be different)
allocate 0x804a008
dealloc 0x804a008
allocate 0x804a008
dealloc 0x804a008
terminate called after throwing an instance of 'std::exception'
what(): std::exception
Aborted
but unless the try-catch block is included, it outputs
allocate 0x804a008
dealloc 0x804a008
allocate 0x804a008
terminate called after throwing an instance of 'std::exception'
what(): std::exception
Aborted
Note: If including the try-catch block, but changing the exception-declaration
of the catch to e.g. 'int', the operator delete still does not get called.
#include
using namespace std;
struct Arena {
void* allocate(std::size_t s) {return ::operator new(s);}
void deallocate(void* p) { ::operator delete(p); }
};
inline void* operator new(std::size_t sz, Arena& a)
{
void* p = a.allocate(sz);
cout << "allocate " << p << endl;
return p;
}
inline void operator delete(void* p, Arena& a)
{
cout << "dealloc " << p << endl;
a.deallocate(p);
}
struct Thrower {
Thrower(bool b) { if (b) throw std::exception();}
};
int main()
{
Arena arena;
Thrower* p = new(arena) Thrower(false);
operator delete(p, arena);
//try {
p = new(arena) Thrower(true); // <- Memory does not get deallocated
//}
//catch (std::exception&) {
//cout << "catch" << endl;
//}
return 0;
}
--
Summary: Placement delete not called when constructor throws
Product: gcc
Version: 4.4.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: kian dot karas dot dev at gmail dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40066