0

既にクリアされているメモリへのアクセスを引き起こすと思われるバグがあります。クラス B (クラス C の構造体インスタンスとクラス D の unique_ptrs を含む) と、クラス B オブジェクトのベクトルを含むクラス A の 2 つのクラスがあります。バグが発生する領域のコード構造は次のとおりです。

void foo{
  A localA(...);
  bar(&localA);
  baz(localA);
}

void bar(A* a) {
  C c1 = constructLocalC1();
  D d1 = constructLocalD1();
  a.insertB(c1, &d1);
}

insertB はクラス B のコンストラクターを呼び出すことに注意してください。

void A::insertB(C c, D* d) {
  bVector.push_back(B(c, d));
}

B::B(C cIn, D* dIn) : c_(cIn) { d_ = make_unique<D>(*dIn); }  

B {
public:
  B(C c, D* d);
  C c_;
  std::unique_ptr<D> d_;
}

の実装は次のようにconstructLocalC1()なります ( に似ていますconstructLocalD1())

 C constructLocalC1() {
   C c1;
   c1.blah = computeBlahParameter(); // blah is of type int
   c1.bleh = computeBlehParameter(); // bleh is of type double
   return c1;
}

baz が localA に存在する c1 (のコピー) にアクセスしようとすると、そこの値が破損し、bar によって設定された値とは異なることが観察されます。この観察からの私の結論は、B を格納するベクトルは、割り当てが解除された要素を格納しているということです。

ここのコード スニペットから根本原因を理解するのは少し複雑であることは承知しています。これは高度に抽象化されているためです。必要な具体的な詳細を提供できることをうれしく思います。

このコード スニペットの潜在的な落とし穴とメモリ リークの原因は何ですか? デバッグにアプローチする良い方法は何ですか?

4

1 に答える 1

0

あなたの問題はおそらく、内部のオブジェクトにメモリを動的に割り当てていないことですbar。明示的または暗黙的に動的に割り当てられていない関数でオブジェクトを作成する場合 (newまたは一時オブジェクトを使用して)、オブジェクトはスタック上に作成され、スコープから出るとすぐに破棄されます。 (あなたの場合、関数が戻ったとき)。1 つのオプションは、ベクトルに挿入されたオブジェクトにメモリを割り当てることですが、適切に処理されないとメモリ リークが発生する可能性があるため、メモリの処理と割り当て解除には細心の注意を払ってください。また、スマート ポインター (Boostライブラリにはそれらの優れた実装がありますが、追加されていますSTL) を使用することもできます。これにより、RAII コンセプト アプローチを使用して、このような状況を防ぐことができます (RAII の詳細については、次のトピックを参照してください。C++ の RAII およびスマート ポインター)。

于 2013-11-06T23:44:39.967 に答える