最近、次のメモリ バグが発生しました。ここでは簡単に見つけることができますが、より複雑なコードでは検出が難しくなる可能性があります。
class Foo : public IFoo {
const Bar& bar_;
public:
Foo(const Bar& bar) : bar_(bar) {
}
void test() {
// access bar_ here
}
};
int baz() {
IFoo* foo = NULL;
if(whatever) {
Bar bar;
foo = new Foo(bar);
}
else {
// create other foo's
}
foo->test(); // segmentation fault
}
バグは、Barすぐに範囲外になり、破棄されてから で使用されることfoo->test()です。Bar1 つの解決策は、を使用してヒープ上に作成することBar* bar = new Bar()です。ただし、特定のコードブロックに固有のものであっても、最後にBar* barアクセスできるようにポインターをトップレベルに保持する必要があるため、これを行うのは好きではありません。deleteBarif(whatever){}
別の解決策は ですがboost::shared_ptr<Bar>、これだけを書くことはできません:
if(whatever) {
boost::shared_ptr<Bar> bar(new Bar());
foo = new Foo(*bar);
}
もすぐに範囲外になりshared_ptr、含まれているオブジェクトが破棄されるためです。
要するに、この問題を取り除くには、どこでも、メンバー変数として、のコンストラクターなどを使用shared_ptrする必要があります。これらの問題を一般的に解消するには、すべての API などで を使用する必要があります。醜い。しかし、それは正しいことですか?これまでのところ、参照カウント オブジェクトを作成するために時々使用してきましたが、API をクリーンな状態に保っています。一度使用すると、どこでも使用しなければならないというこの問題にどのように対処しますか?FooFooshared_ptrshared_ptrshared_ptr
(また、これらの参照カウント ポインターを使用する場合は、本当に必要shared_ptrかどうかweak_ptrなどについて心配し始める必要があります。)
そして、私は何を同等のものとして使用しFoo(const Bar& bar)ますか? Foo(const shared_ptr<const Bar> bar)?
もちろん、別のオプションとして、Barおよび他のオブジェクト内に参照カウントを追加pimplし、独自のカウンターを使用することもできますが、一般的なルールとしては面倒です。