Avoiding heap allocation with "throwing" constructors - c++

Say I have some class Foo which does not define a default constructor and throws in a non-default constructor. When initializing a new object of the type, I'd like to catch any exceptions and return, otherwise continue using the object. I'm noticing it difficult, if at all possible, to initialize this object on the stack or through use of a shared pointer, because I'm trying to avoid managing memory.
Fail 1
Foo f; // doesn't work, no default constructor
try { f = Foo(...); }
Fail 2
try {
Foo f(...)
}
catch(...) {}
// doesn't work, f is inaccessible
Fail 3
boost::shared_ptr<Foo> pf;
try { pf = new Foo(...); } // no assignment operator
Must I...
Foo *f;
try { f = new Foo(...) } // okay, let's just manage the memory
Is there a way?
Edit
Okay, so this works, albeit not the cleanest. Is there a more "standard" way?
boost::shared_ptr<Foo> pf;
try { pf = boost::shared_ptr<Foo>(new Foo(...)); }

Smart pointers have a reset method:
boost::shared_ptr<Foo> f;
//...
f.reset(new Foo(...));
This solves your "Fail #3" and allows you to do what you want.

The correct approach to keep f stack-based is to respect the scope:
try {
Foo f(...);
... entire code using f ...
}
catch(...) {}

One solution could be to use boost::optional (or C++14's std::optional):
boost::optional<Foo> f;
try { f = Foo(...); }

Your smart pointer case and likes work fine if you use the proper .reset() method.
However the question does not fit normal use cases, either the class is misdesigned or you use it incorrectly. Normal use should just go ahead like case#1 with F inside the block. Or without try block and leaving catch to upstream.
EDIT:
Addressing recent comments as well as original issue, I keep my position that try blocks in end-user code are not welcome. For situations where I deal third-party components with certain throw strategy, if it does not fit my needs I write wrappers, converting exception to error-return or error code throwing exception. And use that extended component.
For this case the user is bothered by throwing ctor. So it would be handled by wrapping the ctor in a function:
Foo* new_foo( ARGS )
{
try{
return new Foo( ARGS );
}
catch( const FooException& )
{
return NULL;
}
}
Then have the client code free of try blocks, and more importantly, free of assignments. Just const unique_ptr<Foo> p(new_foo(...)) will do.

Related

What should I do if the 2nd malloc failed in the same constructor

Note that the basis of the question is to use two malloc()s...while suggesting not using malloc() at all is perfectly valid and leads to better design, this is not the point of the question. Perhaps you can think that my client is a psychopath and I am paid to have two malloc()s.
===== Here comes the question itself =====
Say I am stuck with the following class and cannot switch to features such as vector<int>, unique_ptr<int>, etc, while not "modern", it should still work without leaking any memory, whether or not malloc() succeeds:
class Foo {
private:
int *ptr;
public:
Foo () {
this->ptr = (int*)malloc(sizeof(int) * ARR_SIZE);
if (this->ptr == NULL) {
std::bad_alloc exception;
throw exception;
}
}
~Foo () {
free(this->ptr);
}
};
The question appears if I need to malloc() twice within the same constructor:
class Foo {
private:
int *ptr0;
int *ptr1;
public:
Foo () {
this->ptr0 = (int*)malloc(sizeof(int) * ARR_SIZE_0);
if (this->ptr0 == NULL) {
std::bad_alloc exception;
throw exception;
}
this->ptr1= (int*)malloc(sizeof(int) * ARR_SIZE_1);
if (this->ptr1== NULL) {
free(this->ptr0); // QUESTION: Is this needed and does it follow the best practice?
std::bad_alloc exception;
throw exception;
}
}
~Foo () {
free(this->ptr0);
free(this->ptr1);
}
};
I am aware that it could be more advisable in the 2nd case that we create two classes which wrap one pointer each, so the principle of RAII can be thoroughly followed and the above kind of "C-style" free() in constructor is not needed.
The question is, say, for whatever reason, I must have two malloc()s in the constructor, is my design good enough (i.e., not leaking memory and not too verbose)?
Here is a RAII-enabled version.
struct Free
{
void operator()(void* p) const { std::free(p); }
};
template <typename T, typename Deleter = Free>
std::unique_ptr<T, Deleter> raii_malloc()
{
T* obj = static_cast<T*>(std::malloc(sizeof(T)));
if (obj == nullptr) throw std::bad_alloc();
return std::unique_ptr<T, Deleter>(obj);
}
template <typename T, typename Deleter = Free>
std::unique_ptr<T[], Deleter> raii_malloc_array(size_t size)
{
T* obj = static_cast<T*>(std::malloc(sizeof(T) * size));
if (obj == nullptr) throw std::bad_alloc();
return std::unique_ptr<T[], Deleter>(obj);
}
template <typename T>
using fptr = std::unique_ptr<T, Free>;
Now your class looks like this:
class Foo
{
fptr<int[]> ptr0;
fptr<int[]> ptr1;
public:
Foo() : ptr0{raii_malloc_array<int>(ARR_SIZE_0)},
ptr1{raii_malloc_array<int>(ARR_SIZE_1)}
{}
// no destructor needed
};
Note that this version is non-copyable. If you need copying, add a custom copy constructor and/or assignment operator (still no destructor needed).
You can use this with C objects that contain internal pointers or other resources that need to be freed, you just need to supply a different deleter instead of Free.
If unique_ptr is not available, it is extremely easy to roll your own simplified version.
Use std::vector or std::unique_ptr to help manage memory.
Don't use malloc unless you must.
Make sure your class is either safe to copy/move, or not copyable/movable (i.e., deleted constructor, operator=).
Think about how likely you are to handle an out-of-memory case anyway (are you going to open a file and log it while you're out of system memory?), and perhaps just terminate if the allocation fails.
A rather simple way to avoid the issue would be to allocate the necessary memory for your member variables in one go.
class Foo
{
public:
Foo()
{
ptr0 = new int[ARR_SIZE0 + ARR_SIZE1];
ptr1 = ptr0 + ARR_SIZE0;
}
~Foo()
{
delete ptr0[];
}
// PLEASE insert the rest of the
// necessary constructors
// and assignment operators...
private:
int * ptr0;
int * ptr1;
};
Using new instead of malloc here because, if you have to do manual allocations, at least do them using the C++ construct.
Your updated question makes it clearer what the question is about. I feel my first answer still holds value, but this one goes in another direction entirely, which is why I wrote it as a separate answer.
It boils down to:
If I am about to throw an exception from a constructor, do I have to actively release resources previously allocated manually in that constructor?
Yes, you do, for any resources that you would likewise have to free / close / disconnect / ... in the destructor.
If a constructor fails (i.e., throws), the object is not constructed. It is, therefore, not destructed either -- its destructor will never be called. You would lose access to ptr0 and ptr1. Your exception might be caught, the program might continue -- but you would have leaked the memory.
So, again, yes, please do release any resource you would release in the destructor that you already allocated in the constructor before throwing the exception.
All the other comments and remarks also hold true, though. You should strive not to mix C constructs and C++ constructs. Writing idiomatic C++ instead of what is disparagingly called "C with classes" will result in better readable, more stable and likely more efficient code.

Best way to deal "locally" with exceptions thrown in object constructor

I have been thinking for some time now about this question, but I have not found an answer online satisfactory enough, yet. So here I am.
Assumptions
For the sake of clarity let us restrict ourselves to C++11 and a custom object. By custom object, I mean a user-defined class that the developer has full control of. All the code snippets below are not meant to be compilable or even syntactically correct. They just illustrate a concept.
Boundary conditions
Our object has a nontrivial constructor that can throw exceptions if an error is encountered. When constructing this object I would like to catch and deal with the exceptions as close as possible to the object creation point, to make the code more readable and catching only the constructor exceptions and nothing else.
Example 1
This example is not ideal because this is exactly what I am trying to avoid: dealing with constructor exceptions far away from the constructor.
class MyClass {
public:
MyClass() {
throw 1;
}
}
int main() {
try {
MyClass my_obj;
try {
// Do something with my_obj that may throw
} catch (...) {
// deal with exceptions
}
} catch(...) {
// deal with constructor exceptions
}
}
Example 2
Here I use a std::unique_ptr to separate the object declaration and initialization. The downside is that I now create the object on the heap instead of the stack even if I have no strong reason to do that.
class MyClass {
public:
MyClass() {
throw 1;
}
}
int main() {
std::unique_ptr<MyClass> my_obj_ptr;
try {
my_obj_ptr = boost::make_unique<MyClass>();
} catch (...) {
// deal with constructor exceptions
}
// continue to use my_obj
}
Example 3
Modify the object internal state and check that.
class MyClass {
private:
good_internal_state;
public:
MyClass() : good_internal_state(true) {
try {
throw 1;
} catch(...) {
good_internal_state = false;
}
}
bool IsInternalStateGood() {
return good_internal_state;
}
}
int main() {
MyClass my_obj;
if (!my_obj.IsInternalStateGood()) {
// Do something
}
// continue to use my_obj
}
Right now I am leaning towards the Example 2 case but I would like to know what is the most syntactically correct way to accomplish what I want.
I wouldn't say any of those versions is more or less correct (except for some typos). Example 2 looked like the one I would use. Here scoping seems to be the largest problem. The variable needs to declared outside of the try but must be initialized inside. If you don't like to use the heap std::optional could be usefull:
int main() {
std::optional<MyClass> maybeMyClass;
try {
maybeMyClass.emplace(/*constructor parameters*/);
} catch (...) {
// deal with constructor exceptions
}
// continue to use my_obj
maybeMyClass->foo();
}
Allthough the syntax could imply otherwise, the value managed by std::optional is allocated as the footprint of this std::optional (on the stack in this case).
You could also use a factory function createMyClass that would return a std::optional, this would require MyClass to have a move constructor, which shouldn't be to expensive.

How to wrap C allocation returning error code using RAII

I realize that similar questions have been asked elsewhere, but I couldn't find an answer that's a good fit for my function signatures.
Consider this typical pair of C functions:
int initFoo(Options options, Foo* foo);
void freeFoo(Foo* foo);
initFoo takes some options and a pointer to an uninitialized Foo struct. It initializes this struct and returns a result code that indicates whether the initialization was successful. freeFoo frees an initialized Foo struct.
Now assume I want to use these C functions in my C++ code. I want to use RAII, so I need to construct a unique_ptr<Foo> that will automatically call freeFoo on destruction. The best approach I could come up with is this:
template<typename T>
using lambda_unique_ptr = std::unique_ptr<T, std::function<void(T*)>>;
lambda_unique_ptr<Foo> createFoo(Options options) {
Foo* foo = new Foo();
const int resultCode = initFoo(options, foo);
if (resultCode != 0) throw ...;
return lambda_unique_ptr<Foo>(foo, [](Foo* foo) {
freeFoo(foo);
delete foo;
});
}
I'm certain that there must be a more elegant solution. Ideally, something more functional that doesn't require so many individual steps. What I find particularly ugly is the necessity to explicitly allocate the Foo struct on the heap, then explicitly free and delete it in two steps. Any ideas?
Can't you just wrap Foo in a class?
struct FooWrap {
Foo foo;
explicit FooWrap(Options options) {
if (initFoo(options, &this->foo))
throw ...;
}
~FooWrap() {
freeFoo(&this->foo);
}
// XXX: either implement or disable assignment and copy construction
};
Now you can choose whether to just define FooWrap x(42); as an automatic variable or whether to allocate it dynamically with new.

Conditionally dealing with exceptions during initialization of member variables

Hello good folk of StackOverflow.
Is there a better way of dealing with exceptions in the constructor of member variables? I am having to interact with a library class that may or may not throw an exception in it's constructor (cannot be checked ahead of time) and I want to avoid the use of pointers in my class (if there is a crash, I want all destructors to be properly called even if I mess up). I have currently settled on this implementation (included a dummy stub for an example):
class class_I_have_no_control_over{
public:
class_I_have_no_control_over( int someArgument )
{
if( someInternalConditionThatCantBeTestedExternally )
throw anException;
}
class_I_have_no_control_over( )
{ //Does not throw
}
}
class MyClass{
private:
class_I_have_no_control_over memberVariable;
public:
MyClass()
{
try{
class_I_have_no_control_over tempVariable( 24 );
memberVariable = std::move( tempVariable );
}catch(...)
{
class_I_have_no_control_over tempVariable( );
memberVariable = std::move( tempVariable );
}
}
}
The first method I considered is try catch initializer list : i.e.
class MyClass{
private:
OtherClassThatTrowsOnConstruct member;
MyClass()
try:
member()
{//Normal constructor
}
catch(...)
{//Can translate an exception but cant stop it.
}
But that method can only be used to translate exceptions, not stop them (if you don't throw an exception, the run-time will re-throw the original exception).
Some would say to use dynamic allocation (i.e. pointers with new and delete keywords) but as this library handles shared memory between processes, I am a little weary of what would happen to the dynamic memory contents in the event of a crash in one of the applications (ex. destructor never called and another application is waiting for the one that is no longer running never realizing that it is no longer listening).
The first version can be simplified somewhat, without changing its behaviour:
MyClass() try {
memberVariable = class_I_have_no_control_over(24); // move from temporary
} catch (...) {
// no need to do anything; memberVariable is already default-constructed
// Unless the class is so evil that move-assignment might fail and leave
// the target in a messed-up state. In which case you probably want
memberVariable = class_I_have_no_control_over();
// If that fails, you should probably give up and let the exception go.
}
Unless you have further constraints (such as the class not being movable), this is the best way to deal with your situation. If it were unmovable, then dynamic allocation is probably a reasonable option; use a smart pointer, probably std::unique_ptr, to make sure it's destroyed along with the MyClass object.
#include <memory>
class MyClass{
private:
std::unique_ptr<unmovable_evil> memberVariable;
public:
MyClass() try {
memberVariable.reset(new unmovable_evil(24));
} catch(...) {
memberVariable.reset(new unmovable_evil);
}
};
You might also consider boost::optional as a not-quite-standard alternative to dynamic allocation.

Is there a potential for resource leak/double free here?

The following sample (not compiled so I won't vouch for syntax) pulls two resources from resource pools (not allocated with new), then "binds" them together with MyClass for the duration of a certain transaction.
The transaction, implemented here by myFunc, attempts to protect against leakage of these resources by tracking their "ownership". The local resource pointers are cleared when its obvious that instantiation of MyClass was successful. The local catch, as well as the destructor ~MyClass return the resources to their pool (double-frees are protected by teh above mentioned clearing of the local pointers).
Instantiation of MyClass can fail and result in an exception at two steps (1) actual memory allocation, or (2) at the constructor body itself. I do not have a problem with #1, but in the case of #2, if the exception is thrown AFTER m_resA & m_resB were set. Causing both the ~MyClass and the cleanup code of myFunc to assume responsibility for returning these resources to their pools.
Is this a reasonable concern?
Options I have considered, but didn't like:
Smart pointers (like boost's shared_ptr). I didn't see how to apply to a resource pool (aside for wrapping in yet another instance).
Allowing double-free to occur at this level but protecting at the resource pools.
Trying to use the exception type - trying to deduce that if bad_alloc was caught that MyClass did not take ownership. This will require a try-catch in the constructor to make sure that any allocation failures in ABC() ...more code here... wont be confused with failures to allocate MyClass.
Is there a clean, simple solution that I have overlooked?
class SomeExtResourceA;
class SomeExtResourceB;
class MyClass {
private:
// These resources come out of a resource pool not allocated with "new" for each use by MyClass
SomeResourceA* m_resA;
SomeResourceB* m_resB;
public:
MyClass(SomeResourceA* resA, SomeResourceB* resB):
m_resA(resA), m_resB(resB)
{
ABC(); // ... more code here, could throw exceptions
}
~MyClass(){
if(m_resA){
m_resA->Release();
}
if(m_resB){
m_resB->Release();
}
}
};
void myFunc(void)
{
SomeResourceA* resA = NULL;
SomeResourceB* resB = NULL;
MyClass* pMyInst = NULL;
try {
resA = g_pPoolA->Allocate();
resB = g_pPoolB->Allocate();
pMyInst = new MyClass(resA,resB);
resA=NULL; // ''ownership succesfully transfered to pMyInst
resB=NULL; // ''ownership succesfully transfered to pMyInst
// Do some work with pMyInst;
...;
delete pMyInst;
} catch (...) {
// cleanup
// need to check if resA, or resB were allocated prior
// to construction of pMyInst.
if(resA) resA->Release();
if(resB) resB->Release();
delete pMyInst;
throw; // rethrow caught exception
}
}
Here is your chance for a double call to release:
void func()
{
MyClass a(resourceA, resourceB);
MyClass b(a);
}
Whoops.
If you use an RIAA wrapper fro your resources you will be much less likely to make mistakes. Doing it this way is error prone. You are currently missing the copy constructor and assignment operator on MyClass that could potentially lead to a double call to Release() as shown above.
Because of the complexity of handling resource a class should only own one resource. If you have multiple resource delegate their ownership to a class that it dedicated to their ownership and use multiple of these objects in your class.
Edit 1
Lut us make some assumptions:
Resources are shared and counted. You increment the count with Acquire() and decrement the count with Release(). When count reaches zero they are automatically destroyed.
class ReferenceRapper
{
ReferenceBase* ref;
public:
ReferenceWrapper(ReferenceBase* r) : ref (r) {/* Pool set the initial count to 1 */ }
~ReferenceWrapper() { if (ref) { ref->Release();} }
/*
* Copy constructor provides strong exception guarantee (aka transactional guarantee)
* Either the copy works or both objects remain unchanged.
*
* As the assignment operator is implemented using copy/swap it also provides
* the strong exception guarantee.
*/
ReferenceWrapper(ReferenceWrapper& copy)
{
if (copy.ref) {copy.ref->Acquire();}
try
{
if (ref) {ref->Release();}
}
catch(...)
{
if (copy.ref)
{ copy.ref->Release(); // old->Release() threw an exception.
// Must reset copy back to its original state.
}
throw;
}
ref = copy.ref;
}
/*
* Note using the copy and swap idium.
* Note: To enable NRVO optimization we pass by value to make a copy of the RHS.
* rather than doing a manual copy inside the method.
*/
ReferenceWrapper& operator(ReferenceWrapper rhsCopy)
{
this->swap(rhsCopy);
}
void swap(ReferenceWrapper& rhs) throws ()
{
std::swap(ref, rhs.ref);
}
// Add appropriate access methods like operator->()
};
Now that the hard work has been done (managing resources). The real code becomes trivial to write.
class MyClass
{
ReferenceWrapper<SomeResourceA> m_resA;
ReferenceWrapper<SomeResourceB> m_resB;
public:
MyClass(ReferenceWrapper<SomeResourceA>& a, ReferenceWrapper<SomeResourceB>& b)
: m_resA(a)
, m_resB(b)
{
ABC();
}
};
void myFunc(void)
{
ReferenceWrapper<SomeResourceA> resA(g_pPoolA->Allocate());
ReferenceWrapper<SomeResourceB> resB(g_pPoolB->Allocate());
std::auto_ptr<MyClass> pMyInst = new MyClass(resA, resB);
// Do some work with pMyInst;
}
Edit 2 Based on comment below that resources only have one owner:
If we assume a resource has only one owner and is not shared then it becomes trivial:
Drop the Release() method and do all the work in the destructor.
Change the Pool methods so that the construct the pointer into a std::auto_ptr and return the std::auto_ptr.
Code:
class MyClass
{
std::auto_ptr<SomeResourceA> m_resA;
std::auto_ptr<SomeResourceB> m_resB;
public:
MyClass(std::auto_ptr<SomeResourceA>& a, std::auto_ptr<SomeResourceB>& b)
: m_resA(a)
, m_resB(b)
{
ABC();
}
};
void myFunc(void)
{
std::auto_ptr<SomeResourceA> resA(g_pPoolA->Allocate());
std::auto_ptr<SomeResourceB> resB(g_pPoolB->Allocate());
std::auto_ptr<MyClass> pMyInst = new MyClass(resA, resB);
// Do some work with pMyInst;
}
I don't see any leak in this small code.
If the constructor throws exception, then the destructor would not be called, since the object never existed. Hence I don't see double-delete either!
From this article by Herb Sutter :Constructor Exceptions in C++, C#, and Java:
constructor conceptually turns a
suitably sized chunk of raw memory
into an object that obeys its
invariants. An object’s lifetime
doesn’t begin until its constructor
completes successfully. If a
constructor ends by throwing an
exception, that means it never
finished creating the object and
setting up its invariants — and at
the point the exceptional constructor
exits, the object not only doesn’t
exist, but never existed.
A destructor/disposer conceptually
turns an object back into raw memory.
Therefore, just like all other
nonprivate methods,
destructors/disposers assume as a
precondition that “this” object is
actually a valid object and that its
invariants hold. Hence,
destructors/disposers only run on
successfully constructed objects.
I think this should clear your doubts!
Your code is fine. But to make it even better, use some kind of smart-pointer!
Edit: for example you can use shared_ptr:
class SomeExtResourceA;
class SomeExtResourceB;
class MyClass {
private:
// These resources come out of a resource pool not allocated with "new" for each use by MyClass
shared_ptr<SomeResourceA> m_resA;
shared_ptr<SomeResourceB> m_resB;
public:
MyClass(const shared_ptr<SomeResourceA> &resA, const shared_ptr<SomeResourceB> &resB):
m_resA(resA), m_resB(resB)
{
ABC(); // ... more code here, could throw exceptions
}
}
};
void myFunc(void)
{
shared_ptr<SomeResourceA> resA(g_pPoolA->Allocate(), bind(&SomeResourceA::Release, _1));
shared_ptr<SomeResourceB> resB(g_pPoolB->Allocate(), bind(&SomeResourceB::Release, _1));
MyClass pMyInst(resA,resB);
// you can reset them here if you want, but it's not necessery:
resA.reset(), resB.reset();
// use pMyInst
}
I find this solution with RAII much simpler.
Just put if (pMyInst) { ... } around release/delete code in your catch and you are fine.
The classic usage to explicitly take ownership is the std::auto_ptr
Something like this:
std::auto_ptr<SomeResourceA>(g_pPoolA->Allocate()) resA;
std::auto_ptr<SomeResourceB>(g_pPoolB->Allocate()) resB;
pMyInst = new MyClass(resA.release(),resB.release());
You transfer the ownership when you call the constructor.