我一直在读到我不应该抛出一个std::string
或其他一些分配内存的类。喜欢这里或更重要的是第 3 点。 -不要嵌入std::string
对象。
所以现在我试图在我的项目中插入boost::exception,我看到了什么:很多字符串。
为什么 boost 不遵守自己的建议?
如果我有不能硬编码的参数,比如安全的配置文件,我怎么能把它们放到异常中,而不使用std::string
?
还是指南不只使用std::string
一个尽可能少使用std::string
的指南?我有点困惑……
我做了一些研究。如果我错了,请纠正我。
如果我理解正确,这完全是关于抛出期间的分配以及分配的内存发生了什么。因此,如果我在构造函数中分配内存并且无法在异常的析构函数中释放内存,则会丢失内存,这将产生内存泄漏。但是在抛出之前分配这个是可以的,所以异常是干净的。
我试过这个:
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;
}
结果是,我得到了bad_alloc和巨大的内存泄漏。
现在,如果我之前进行分配,它也会抛出 bad_alloc 但在创建异常之前。
我对异常概念的例外是:
谁在乎?如果我的程序中有一个 bad_alloc,由于 memory_leak 或其他原因(我说的是 PC 上的程序而不是微控制器),我还有其他问题。也许我可以弄清楚发生了 bad_alloc,但是在哪里呢?在我的 alloc 函数期间(可能是 1000 个)或在std::string
(我知道它是字符串但......不可能操纵字符串的内存......或者它消散)。
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) {
....
}
进而?我应该试着弄清楚它发生在哪里吗?因此我会使用valgrind而不是例外。
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
}
或者我应该操纵错误消息并记录它,最终会抛出下一个bad_alloc。
请不要误解我的意思。自从我看到了 boost::exception 我已经重写了我的异常类(直到等待答案),但我也认为没有必要捡起每一粒沙子。