9

コードに問題があり、非常に奇妙な症状が見られます。

  1. コードは、次のバージョンのコンピューターでコンパイルされています。

    を。GCC バージョン: 4.4.2

    b. CMAKE バージョン: 2.8.7

    c. QNX (オペレーティング システム) バージョン: 6.5.0

また、一部のメモリを解放して関数を終了する際に、コードにセグメンテーション違反があります (どのコードでも終了せず、関数を終了するだけです)。

これについての奇妙な点は次のとおりです。

  1. コードはリリース モードで実行しますが、デバッグ モードでは実行しません。

    を。コードはスレッド化されているため、これは競合状態を示しています。

    b. デバッグモードにしてデバッグできません。

  2. すべてが同じバージョンの Workmates マシンでコンパイルされたコードには、この問題はありません。

    を。これに関する奇妙な点は、同僚のコードが機能することですが、彼のマシンでコンパイルして作成されたバイナリは同じで、約 6mB 大きいことです。

迷惑なことに、コードが大きすぎて仕事にも使えないため、コードを投稿できません。しかし、誰でもこれを修正するための道筋を教えてもらえますか?

QNX を使用しているため、デバッグ ツールが限られているため、Valgrind を使用できません。Valgrind は QNX でサポートされていないため、GDB はあまり役に立ちません。

似たような/同じ問題を抱えていて、その原因と解決方法を知っている人を探しています。

編集:

すっごく... 原因は分かったけど、どうやって起こったのかまだ少し混乱している。

犯人コードはこれでした:

Eigen::VectorXd msBb = data.modelSearcher->getMinimumBoundingBox();

の定義getMinimumBoundingBoxは次のとおりです。

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();

そして、常に として初期化される VectorXd を返しますVectorXd output(6, 1)。だから私はすぐに、VectorXdが初期化されていないが、これに変更されているためだと思いました:

Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();

しかし、これはうまくいきませんでした。実際、関数の定義を次のように変更して修正する必要がありました。

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);

そしてこれへの呼び出し

Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);

だから今、新しい質問:

なんてこったい?最初の変更が機能しなかったのに、2 番目の変更が機能したのはなぜですか? なぜ参照渡しをしなければならないのですか? ああ、大きな問題です。同僚がコンパイルして実行したとき、どうしてこれが壊れなかったのですか? それは単純なメモリエラーです。特に、コンパイラと他のすべての重要なものが同じであるため、コンパイルするコンピューターに依存するべきではありません!!??

助けてくれてありがとう。

4

2 に答える 2

8

... 彼のマシンでコンパイルして作成されたバイナリは同じですが、約 6MB 大きくなっています。

違いが何であるかを理解することは価値があります (たとえ彼のビルドが隠れているのに、あなたのビルドが本当のバグであっても):

  • まったく同じコードをコンパイルしていることを再確認してください (コミットされていないローカルの変更がない、インクルード検索パスに余分なヘッダーがないなど)。
    • cmake で gcc 引数にスイッチを追加してトリプルチェックを-E行うと、通常のコンパイルと同じインクルード パスでファイルが前処理されます。プリプロセッサ出力の差分
  • nm2 つのリンクされた実行可能ファイルからの出力または必要なものを比較objdumpします。一部のシステムまたはサードパーティ ライブラリが 1 つのボックスで異なるバージョンである場合、ここに表示されることがあります。
  • 動的にリンクされている場合は出力を比較しldd、両方が同じライブラリバージョンを取得していることを確認してください
    • 可能であれば、実行時に実際に取得するライブラリのバージョンも比較してください。次のいずれかを実行していただければ幸いです: を実行plddし、 の.soエントリを比較し、 / //proc/pid/mapの下でプロセスを実行し、ランタイム リンカー アクティビティを比較します。stracedtracetruss

コードについては...これが機能しない場合:

Eigen::VectorXd ModelSearcher::getMinimumBoundingBox();
// ...
Eigen::VectorXd msBb(6, 1); msBb = data.modelSearcher->getMinimumBoundingBox();

そしてこれは:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);
// ...
Eigen::VectorXd msBb(6, 1); data.modelSearcher->getMinimumBoundingBox(msBb);

おそらく代入演算子に問題があります。浅いコピーを実行し、ベクトルに動的に割り当てられたメモリがある場合、同じポインターを保持する 2 つのベクトルが作成され、両方がfree/deleteそれになります。

演算子がまったく定義されていない場合、デフォルトではこのシャロー コピーが実行されることに注意してください。

于 2012-11-20T10:11:40.677 に答える
0

あなたは次のものから変更する必要があると言いました:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd& input);

以前は何だったの?

それがあった場合:

void ModelSearcher::getMinimumBoundingBox(Eigen::MatrixXd input);

コピー コンストラクター/代入演算子が適切に実装されていなかったため、問題が発生した可能性があります。

両方がどのように実装されているかを確認してください。ここに役立つかもしれない情報があります。

于 2012-11-20T09:07:04.960 に答える