I'm always reading that I should not to throw a std::string
or some other classes allocating memory. like here or more importantly here on point 3. - Don't embed a std::string
object.
So now I'm trying to insert boost::exception to my project and what do I see: lots of strings.
Why doesn't boost comply with its own recommendation?
And if I have parameters which can't be hardcoded, like safed in an config-file, how can I put them into an exception, without using std::string
?
Or is the guideline don't use std::string
only a do use std::string
as seldom as possible guideline? I'm a bit confused...
I've done some research. Please correct me if i'm wrong.
If I understand it right, it's all about the allocation during the throw and what is happening to the allocated memory. So the memory gets lost if I allocate it in the constructor and it can't be freed in the destructor of the exception, that will produce a memory-leak. But it's okay to allocate this before throwing, so the exception is clean.
I tried this:
struct xexception {
int *ttt[10];
xexception() {
ttt[0] = new int[0xfffffffL];
ttt[1] = new int[0xfffffffL];
ttt[2] = new int[0xfffffffL];
ttt[3] = new int[0xfffffffL];
ttt[4] = new int[0xfffffffL];
ttt[5] = new int[0xfffffffL];
ttt[6] = new int[0xfffffffL];
ttt[7] = new int[0xfffffffL];
ttt[8] = new int[0xfffffffL];
ttt[9] = new int[0xfffffffL];
}
~xexception() throw() {
//never happen
delete[] ttt[0];
delete[] ttt[1];
delete[] ttt[2];
delete[] ttt[3];
delete[] ttt[4];
delete[] ttt[5];
delete[] ttt[6];
delete[] ttt[7];
delete[] ttt[8];
delete[] ttt[9];
}
};
int main(int argc, const char *argv[]) {
try {
throw(xexception());
}
catch (const xexception &e) {
std::cerr << "\nttt " << e.ttt[0][0] << std::endl;
}
catch (std::bad_alloc) {
std::cerr << "bad alloc" << std::endl;
}
return 0;
}
The result is, I get the bad_alloc and a huge memory leak.
Now if I do the allocation before, it also throws the bad_alloc but before the exception is created.
My exception to the exception concept is:
Who cares? If I have a bad_alloc in my program, because of a memory_leak or something else (I'm talking about programs on PCs not microcontrollers) I have other problems. Maybe I can figure out that a bad_alloc happened, but where? On my alloc during a function (one of maybe 1000) or in the std::string
(well I know it's the string but ... no possibility to manipulate the memory of the string... or its to dissipated).
try {
// where is the error???
int *x = new int[100]; // here?
....
int *y = new int[100]; // or here?
....
int *z = new int[100];
....
int *w = new int[100];
....
int *t = new int[100];
....
int *f = new int[100];
....
std::string str("asdfasdfasdfasdfasdfasdfasdf"); // maybe here
}
catch (the error) {
....
}
And then? Shall I try to figure out where it's happening? Therefore I would use valgrind not exceptions.
void foo() {
int *i = new int[1];
foo();
}
try {
foo();
}
chatch( bad_boy ) {
go_exception_handler_go(parameters); // oh, shit happens: also an stack_overflow may happend, cause stack is also full
}
Or shall i manipulate the errormessage and log it, what definitively would throw the next bad_alloc.
Please don't misunderstand me. Since I've seen the boost::exception I've rewritten my exception class (till waiting on an answer) but I also think it is not really necessary to pick up every grain of sand.