How to safely deal with an array pointer when throwing an exception - c++

When trying to encapsulate C API in C++ method, i found a problem in throwing an exception:
int status;
char* log = nullptr;
int infoLogLength;
getFooStatus(&status);
getFooLogLength(&infoLogLength);
if (!status) {
log = new char[infoLogLength];
getFooLog(infoLogLength, log);
throw std::runtime_error(log);
}
I am not allowed to modify the interface methods in any way.
From what i understand, i am required to reserve memory for the method to fill, and operate on that. However, throwing the exception will return from the method, not letting me to free the resources. Is my code correct, or should i go around this in some other way?

std:runtime_error expects a std::string, so give it a std::string instead of a char*:
int status;
getFooStatus(&status);
if (!status) {
int infoLogLength;
getFooLogLength(&infoLogLength);
std::string log(infoLogLength, '\0');
getFooLog(infoLogLength, &log[0]);
throw std::runtime_error(log);
}
Alternatively, you can pass a char*, simply allocate it in a way that promoted auto-freeing, eg:
int status;
getFooStatus(&status);
if (!status) {
int infoLogLength;
getFooLogLength(&infoLogLength);
std::vector<char> log(infoLogLength);
getFooLog(infoLogLength, &log[0]);
throw std::runtime_error(&log[0]);
}

As far as I know runtime_error has two overloads, one with a const *char and another as const string&.
I believe constructing a std::string as a local variable and passing that to runtime_error should result in it being cleaned up properly.

There is a simple way to deal with exceptions, without having to refactor the code so that the array is managed by an object whose destructor cleans it up. Namely:
char* log = nullptr;
try {
int status;
int infoLogLength;
getFooStatus(&status);
getFooLogLength(&infoLogLength);
if (!status) {
log = new char[infoLogLength];
getFooLog(infoLogLength, log);
throw std::runtime_error(log);
}
} catch (...) { // special C++ syntax: "catch any exception"
delete [] log;
throw; // special C++ syntax: "re-throw" current exception
}
If all you have is a single catch (...), it looks a lot as if C++ supports finally. The difference betwen catch (...) and a finally feature is that catch (...) does not execute unconditionally: it only executes if there isn't a more specific catch. So, if you were to add additional catch clauses in the same try block, they would all have to repeat the delete [] log clean-up action.
This could be mitigated by using nesting:
try { // real exception-handling try
try { // try for unwind protection only
...
} catch (...) {
// clean-up statements
throw;
}
} catch (actual_error &err) {
...
} catch (another_exc_type &exc) {
...
}

Related

how to write clean try/catch block when find function returns a reference?

I have some code that looks like this:
const SomeType & elt = x.find();
try {
// ... do something with elt ...
} catch (...) {
// handle processing exception
}
And it works, but due to changing circumstances, it's now possible for that find() method to throw a "not found" exception, which I need to catch.
What I'd like to write would be
try {
const SomeType & elt = x.find();
} catch (...) {
// handle "not found" exception
return;
}
try {
// ... do something with elt ...
} catch (...) {
// handle processing exception
}
But of course this doesn't work, because elt is no longer in scope by the time its processing block is reached. I can't rearrange this to
const SomeType & elt;
try {
elt = x.find();
} catch (...) {
// handle "not found" exception
return;
}
because of course reference types in C++ aren't allowed to be uninitialized. So I'm left with the options of temporarily setting elt to be a reference to a dummy object of type SomeType, which I'd rather not do, or nesting the try/catch blocks, like this:
try {
const SomeType & elt = x.find();
try {
// ... do something with elt ...
} catch (...) {
// handle processing exception
}
} catch (...) {
// handle "not found" exception
}
I don't like this, either: the nesting is confusing, and I don't like the way the "not found" exception handler is hiding down there at the end.
Can anyone think of a better way to arrange this? (In C, of course, we'd just have the find function return a null pointer in the not-found case, and handle it that way, but I like to try not to be an old C programmer when I'm writing C++, and anyway x.find() is already set up to return a reference, not a pointer.)
If exceptions are different, you might use the same try block:
try {
const SomeType& elt = x.find();
// ... do something with elt ...
} catch (const NotFoundException&) {
// handle "not found" exception
} catch (...) {
// handle processing exception
}
else rebinding reference is not allowed, but might be simulated by pointer or std::reference_wrapper in general,
And optional reference (not allowed neither in std, but boost allow it) might be simulated by pointer or std::optional<std::reference_wrapper<T>>.
So:
const SomeType* eltPtr = nullptr;
try {
eltPtr = &x.find();
} catch (const NotFoundException&) {
// handle "not found" exception
return;
}
const SomeType& elt = *eltPtr;
try {
// ... do something with elt ...
} catch (...) {
// handle processing exception
}
Split into another function:
void func1()
{
try {
const SomeType & elt = x.find();
func2(elt);
} catch (...) {
// handle "not found" exception
}
}
void funct2(const SomeType & elt)
{
try {
// ... do something with elt ...
} catch (...) {
// handle processing exception
}
}
Though in general I find your interface slightly disturbing to require all these try/catch blocks in the first place. Unfortunately it is hard to offer advice on how to improve the general style with such little information.
It will not be to everyone's taste (the behaviour is defined by the way), but you could use
#include <functional>
std::reference_wrapper<const SomeType> elt = elt;
try {
elt = x.find();
} catch (...) {
// handle "not found" exception
return;
}
Arguably the setting of elt to itself is an abuse of std::reference_wrapper, which has its default and move constructors deleted by design: I'm circumventing that.
Essentially std::refernce_wrapper is a pointer under the hood but you can rebind it, which is essentially what you want to do here.

C++ Windows DLL: Exception Handling in Different Function

This is more of a design suggestion I need. Below code is from a C++ dll that am working on and this dll is called by many client executables. InputParams is a pointer to client exe.
The dll calls functions in the client to get certain values and the client doesn't have any exception build into it. So i need to implement exception handling in dll code.
for e.g., in the line input->getName, if it returns a NULL pointer or if status == ERROR, then I need to throw exception and catch it in GetNumbers function.
void Metrics::GetNumbers(InputParams* input, OutputParams* output)
{
int i, x, k;
int status = 0;
char* mesg;
try{
const char* name = input->getName(&status, &mesg); //this returns a name string
//and status will contain whether success or failure and mesg will have any error
//messages.
const char* age = input->getAge(&status, &mesg);
//Many other similar calls to client
vector <int> myVectorNumers* = input->getNumberArray(&status, &mesg);
vector <int> myVectorInfos* = input->getInfoArray(&status, &mesg);
//Many other similar calls to client;
}
catch (std::exception e&)
{
// TODO
}
catch (string msg)
{
// TODO
}
I came up with a way of doing it. And this is the snippet of code.
string errorMsg = "";
const char* name = input->getName(&status, &mesg);
if (name == NULL || status == ERROR) // ERROR == 0
{
errorMsg = mesg;
throw errorMsg;
}
const char* age = input->getAge(&status, &mesg);
if (age== NULL || status == ERROR)
{
errorMsg = mesg;
throw errorMsg;
}
//Same for other calls to client using **input** pointer
Now as you see, I have to duplicate almost the same code in every place were there should be an exception check.
What am looking for is?
string errorMsg = "";
const char* name = input->getName(&status, &mesg);
CheckException(name, status, mesg, &errorMsg); // this function should do the error check and then throw the exception. And that exception should be caught by catch block in **GetNumbers** function.
const char* age = input->getAge(&status, &mesg);
CheckException(age, status, mesg, &errorMsg);
I have no idea whether even this is possible.
So a dummy implementation of CheckException will look like......
std::exception CheckException (/*1st parameter needs to be template type*/T* var, int status, string mesg, string *errorMsg)
{
if (var == NULL || status == ERROR)
{
errorMsg = mesg;
return /*TODO*/; //Not sure how to return a throw
}
}
1st of all, is this possible? Or is there a better way of doing this?
If you can provide me some sample code, that will be great!
Exceptions are not allowed to pass over the DLL boundary into the calling executable. The caller is not guaranteed to know how to handle an exception properly, especially in regards to cleanup, even if the executable and DLL are compiled with the same compiler. Or, the caller may not even understand what an exception is at all, if the executable and DLL are compiled in different languages.
If you need to convey error information to the caller, you must do so using a return value, an output parameter, a separate function call, etc. Things that are more-or-less universally supported across compilers/languages.
DO NOT throw exceptions over the DLL boundary into the caller!
UPDATE
You are already catching std::exception& in GetNumbers() (though, it really should be const std::exception & instead), so simply have CheckException() actually throw a std::exception object, don't try to return it, eg:
template<typename T>
void CheckException (const T *var, int status, const string &mesg)
{
if (var == NULL || status == ERROR) {
// or make a custom class derived from std::exception, if you want...
throw std::runtime_error(mesg);
}
}
...
try
{
const char* name = input->getName(&status, &mesg);
CheckException(name, status, mesg);
const char* age = input->getAge(&status, &mesg);
CheckException(age, status, mesg);
// Many other similar calls to client...
vector<int> *myVectorNumers = input->getNumberArray(&status, &mesg);
CheckException(myVectorNumers, status, mesg);
vector<int> *myVectorInfos = input->getInfoArray(&status, &mesg);
CheckException(myVectorInfos, status, mesg);
// Many other similar calls to client...
}
catch (const std::exception e&)
{
// TODO
}

How do I run a cleanup code on the function exit?

C++ classes provide RAII idiom. Therefore you don't have to care about exceptions:
void function()
{
// The memory will be freed automatically on function exit
std::vector<int> vector(1000);
// Do some work
}
But if you have (for some reasons) to use some pure C API, you have either to create C++ wrappers around it or to use try/catch blocks
void function()
{
int *arr = (int*)malloc(1000*sizeof(int));
if (!arr) { throw "cannot malloc"; }
try
{
// Do some work
}
catch (...)
{
free(arr); // Free memory in case of exception
throw; // Rethrow the exception
}
// Free memory in case of success
free(arr);
}
Even if you use C++ classes with RAII idiom, sometimes you have to write a code with strong exception-safety guaranty:
void function(std::vector<const char*> &vector)
{
vector.push_back("hello");
try
{
// Do some work
vector.push_back("world");
try
{
// Do other work
}
catch (...)
{
vector.pop_back(); // Undo vector.push_back("world")
throw; // Rethrow the exception
}
}
catch (...)
{
vector.pop_back(); // Undo vector.push_back("hello");
throw; // Rethrow the exception
}
}
But these constructions are quite bulky.
Is there any way to force to run some cleanup code at function exit? Something similar to atexit, but in a function scope...
Is there any way to run some rollback code in case of exception without using nested try/catch blocks?
I would like to have some operators or functions that would work like this:
void function(std::vector<const char*> &vector)
{
int *arr = malloc(1000*sizeof(int));
onexit { free(arr); }
vector.push_back("hello");
onexception { vector.pop_back(); }
// Do some work
vector.push_back("world");
onexception { vector.pop_back(); }
// Do other work
}
If it is possible to create such functions, are there any reasons to avoid using them? Are there such constructs in other programming languages?
I have created macros that implement this functionality. They generate a local variable that runs a cleanup code in the destructor using C++11 lambda functions. The std::uncaught_exception function is used to check if there is any exception currently thrown. Creating the variable itself shouldn't throw any exceptions because a lambda with all variables captured by reference is used to create the variable (such lambdas do not throw exceptions in copy/move constructors).
#include <exception>
// An object of the class below will run an arbitrary code in its destructor
template <bool always, typename TCallable>
class OnBlockExit
{
public:
TCallable m_on_exit_handler;
~OnBlockExit()
{
if (always || std::uncaught_exception())
{ m_on_exit_handler(); }
}
};
// It is not possible to instantiate an object of the 'OnBlockExit' class
// without using the function below: https://stackoverflow.com/a/32280985/5447906.
// Creating of an object of the 'OnBlockExit' class shouldn't throw any exception,
// if lambda with all variables captured by reference is used as the parameter.
template <bool always, typename TCallable>
OnBlockExit<always, TCallable> MakeOnBlockExit(TCallable &&on_exit_handler)
{
return { std::forward<TCallable>(on_exit_handler) };
}
// COMBINE is needed for generating an unique variable
// (the name of the variable contains the line number:
// https://stackoverflow.com/a/10379844/544790)
#define COMBINE1(X,Y) X##Y
#define COMBINE(X,Y) COMBINE1(X,Y)
// ON_BLOCK_EXIT generates a variable with the name
// in the format on_block_exit##__LINE__
#define ON_BLOCK_EXIT(always, code) \
auto COMBINE(on_block_exit,__LINE__) = MakeOnBlockExit<always>([&]()code)
// Below are target macros that execute the 'code' on the function exit.
// ON_FINALLY will allways execute the code on the function exit,
// ON_EXCEPTION will execute it only in the case of exception.
#define ON_EXCEPTION(code) ON_BLOCK_EXIT(false, code)
#define ON_FINALLY(code) ON_BLOCK_EXIT(true , code)
Here is an example how to use these macros:
void function(std::vector<const char*> &vector)
{
int *arr1 = (int*)malloc(800*sizeof(int));
if (!arr1) { throw "cannot malloc arr1"; }
ON_FINALLY({ free(arr1); });
int *arr2 = (int*)malloc(900*sizeof(int));
if (!arr2) { throw "cannot malloc arr2"; }
ON_FINALLY({ free(arr2); });
vector.push_back("good");
ON_EXCEPTION({ vector.pop_back(); });
auto file = fopen("file.txt", "rb");
if (!file) { throw "cannot open file.txt"; }
ON_FINALLY({ fclose(file); });
vector.push_back("bye");
ON_EXCEPTION({ vector.pop_back(); });
int *arr3 = (int*)malloc(1000*sizeof(int));
if (!arr3) { throw "cannot malloc arr3"; }
ON_FINALLY({ free(arr3); });
arr1[1] = 1;
arr2[2] = 2;
arr3[3] = 3;
}
All cleanup code is executed in reverse order (in the order opposite to the order of the ON_FINALLY/ON_EXCEPTION macros appearance in the function). The cleanup code is executed only if control passes beyond the corresponding ON_FINALLY/ON_EXCEPTION macro.
Check the following link to see the output of the demo program execution: http://coliru.stacked-crooked.com/a/d6defaed0949dcc8
C++ has destructors which is what you need. An object that does whatever you need done at scope exit in its destructor that you then create an instance of on the stack in the scope where you need the work done, will get destroyed when the scope is left and then do the work at that time.
ScopeGuard is the right choice for you. It basically calls the function you specify at destructor.
So your code can be:
void your_function() {
scope_guard guard = [&vector]() {
vector.pop_back();
};
// your code
guard.dismiss(); // success
}

Access variable outside try-catch block

I have the following code:
class ClassA
{
public:
ClassA(std::string str);
std::string GetSomething();
};
int main()
{
std::string s = "";
try
{
ClassA a = ClassA(s);
}
catch(...)
{
//Do something
exit(1);
}
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
I would like the last line could access the a variable. How could I achieve that, given ClassA doesn't have default constructor ClassA() and I would not like to use pointers? Is the only way to add a default constructor to ClassA?
You can't or shouldn't. Instead you could just use it within the try block, something like:
try
{
ClassA a = ClassA(s);
std::string result = a.GetSomething();
}
catch(...)
{
//Do something
exit(1);
}
The reason is that since a goes out of scope after the try block referring to the object after that is undefined behavior (if you have a pointer to where it were).
If you're concerned with a.GetSomething or the assignment throws you could put a try-catch around that:
try
{
ClassA a = ClassA(s);
try {
std::string result = a.GetSomething();
}
catch(...) {
// handle exceptions not from the constructor
}
}
catch(...)
{
//Do something only for exception from the constructor
exit(1);
}
You can use some sort of optional or just use std::unique_ptr.
int main()
{
std::string s = "";
std::unique_ptr<ClassA> pa;
try
{
pa.reset(new ClassA(s));
}
catch
{
//Do something
exit(1);
}
ClassA& a = *pa; // safe because of the exit(1) in catch() block
std::string result = a.GetSomething();
//Some large amount of code using 'a' out there.
}
Of course, just extending the try block to include the usage of a is the simplest solution.
Also, if you were really planning to exit(1) or otherwise abort the program on failure then simply don't put a try block here at all. The exception will propagate up, aborting the program if it is not caught .
One alternative is to use std::optional . This is the same sort of concept as using a pointer, but it uses automatic allocation and so you are less likely to create a memory leak. This is currently experimental status; you can use boost::optional instead if your compiler doesn't have std::experimental::optional:
#include <experimental/optional>
using std::experimental::optional;
using std::experimental::in_place;
// ...
optional<ClassA> a;
try
{
a = optional<ClassA>(in_place, s);
}
catch(...)
{
// display message or something
}
std::string result;
if ( a )
result = a->GetSomething();
I'd like to reiterate though that this is a bit of a spaghetti style and it'd be better to design your code differently so you aren't continually testing whether construction succeeded or failed.
This requires ClassA be movable or copyable. The in_place is a special argument which invokes a perfect forwarding constructor for the remaining arguments. Without in_place you can only give an actual ClassA as constructor argument, it doesn't consider implicit conversions to ClassA. (This is how optional avoids the ambiguity between copy-construction and list-initialization from object of the same type).

Can exception handling of object whose constructor throw an exception be near its stack-based creation on code?

I'm trying to make my C++ code exception-safe, and got a problem that neither asking friends nor searching web will help.
On my understanding, when creating an object with constructor potentially throw an exception, the code for creation needs to be enclosed with try block and exception handling is done in catch(){}.
If the creation is heap-based(e.g. newed with default allocator), I can place exception handling code near the creation like this:
void f() {
// work unrelated to Hoge object here
try {
Hoge *pHoge = new Hoge(); // could throw an exception
} catch(HogeException& ex) {
// handle exception
}
// rest of work here
}
However, if the creation is stack-based, I can't find ways to do that and resort to code like below due to the scope of try block:
void g() {
// work unrelated to Hoge object here
try {
Hoge hoge; // could throw an exception
// rest of work here
} catch(HogeException& ex) {
// handle exception
}
}
If // rest of work code above is large, the distance of locations between object creation and exception handling could be long, decreasing code readability...
I prefer the exception handling code is near object creation(and maybe that is one of the concepts of try-catch structure). Is there any solutions?
Delegate the // rest of work to a helper function, and pass a Hoge& to that function:
void RestOfWork(Hoge& hoge)
{
// rest of work here
}
void g() {
// work unrelated to Hoge object here
try {
Hoge hoge;
RestOfWork(hoge);
// rest of work here
} catch(HogeException& ex) {
// handle exception
}
}
Incidentally, Hoge hoge(); doesn't do what you think it does. You probably think that you are declaring an object named hoge of type Hoge, and initializing it by calling the default constructor. What you're actually doing is declaring a function named hoge which takes no parameters and returns a Hoge by-value. I've fixed this in my code above.
Edit Indeed, as suggested by #LightnessRacesInOrbit, the construction of the Hoge object can take place in the deferral function as well, such as with:
void RestOfWork()
{
Hoge hoge;
// rest of work here
}
void g() {
// work unrelated to Hoge object here
try {
RestOfWork();
} catch(HogeException& ex) {
// handle exception
}
}
A reasonable way to do this is to use a nullable single-item container, e.g. boost::optional:
void g() {
// work unrelated to Hoge object here
boost::optional<Hoge> opt_hoge;
try {
opt_hoge = boost::in_place<Hoge>();
} catch(HogeException& ex) {
// handle exception
}
Hoge &hoge = *opt_hoge;
// rest of work here
}
If you can't use Boost, std::unique_ptr would work at the cost of a heap allocation:
void g() {
// work unrelated to Hoge object here
std::unique_ptr<Hoge> opt_hoge;
try {
opt_hoge = std::unique_ptr<Hoge>(new Hoge);
} catch(HogeException& ex) {
// handle exception
}
Hoge &hoge = *opt_hoge;
// rest of work here
}