2

私はここでロープの終わりにいます。私はシングルスレッドの C++ プログラムを持っています。ここにいくつかの経験的データと背景情報があります。私は最も重要なキーワードを強調しようとしました。

  • 私が話しているセクション全体には、標準 C++ ライブラリが実行する可能性のあるメモリ (割り当て解除) 呼び出し ( が含まれる) を除いて、syscalls はありません。これは純粋に論理的なアルゴリズムです。std::set
  • これの動作は、入力に応じて決定論的である必要がありますが、私は変化しません。
  • バグが明らかになった場合、プログラムは無限ループのように見えるものに陥り、境界を超えてメモリの割り当てを開始するように見えます。
  • バグは予想どおりには現れませ。コマンド ラインからプログラムを実行できますが、バグが現れることもあります (おそらく 30% ~ 50%)。
  • プロンプトから直接プログラムを実行するのではなく、gdb または valgrind でプログラムを実行すると、バグがなくなり、プログラムが停止することはありません。
  • 最良の部分は次のとおりです。問題を(テンプレート化された)非仮想メンバー関数呼び出しまで追跡しました。電話をかける直前に、ターミナルに表示されるメッセージをstd::coutに出力します。関数内の最初の行にもデバッグ メッセージがありますが、これは表示されません

もう合理的な説明は見当たりません。進め方のヒントが得られるかもしれません。


編集:コードの重要な行。参照できるように行番号を変更し、無関係な部分を省略したため、すべてが最良の意味を持っているわけではありません。

a.cpp

 10     std::set<Array const*>* symbols;
 11     std::set<Array const*> allSymbols;
 12     symbols = &allSymbols;
 //  ... allSymbols are populated with std::inserter
 15     std::cout << "eval; cd = " << &cd << ", cg = " << &cd.cg << std::endl;
 16     senderConstraints = cd.cg.eval(*symbols);

b.cpp

 31     template <typename ArrayContainer>
 32     ConstraintList eval(ArrayContainer const request) {
 33       std::cout << "inside eval ... going to update graph now" << std::endl;

出力の最後の行は次のとおりです。

eval; cd = 0x2e6ebb0, cg = 0x2e6ebc0

その後、無限ループに陥ります。

4

1 に答える 1

5

たぶん、変更すると2行目が出力されます

ConstraintList eval(ArrayContainer const request)

ConstraintList eval(ArrayContainer const & request)

その場合、allSymbols12 行目と 15 行目の間で の状態が破損しているか、コードが実際には次のようになっています。

std::set<Array const*>* symbols;
{
    std::set<Array const*> allSymbols;
    symbols = &allSymbols;
    //  ... allSymbols are populated with std::inserter
}
std::cout << "eval; cd = " << &cd << ", cg = " << &cd.cg << std::endl;
senderConstraints = cd.cg.eval(*symbols);

シンボルはすでに破壊されたオブジェクトを参照するため、これは UB です。

于 2012-06-26T11:22:07.657 に答える