私は常に、std::string
またはメモリを割り当てる他のクラスをスローすべきではないことを読んでいます。ここのように、またはもっと重要なことに、ポイント 3のここのように。 -オブジェクトを埋め込まないでくださいstd::string
。
だから今、私は自分のプロジェクトにboost::exceptionを挿入しようとしています。
ブーストが独自の推奨事項に準拠しないのはなぜですか?
また、構成ファイルで保護されているように、ハードコーディングできないパラメーターがある場合、使用せずにそれらを例外に入れるにはどうすればよい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 が発生したことがわかるかもしれませんが、どこでしょうか? 関数中の割り当て(おそらく1000のうちの1つ)または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 を見たので、(回答を待つまで) 例外クラスを書き直しましたが、すべての砂粒を拾う必要はないと思います。