8

Parasoft C++testを使用して、コードを静的に分析します。次のようなコードで問題が発生しています。

void foo(int* x) {
    try {
        bar();
    } catch(...) {
        delete x;
        throw;
    }

    *x;
}

*x;次の行で警告します。

解放されたメモリは、その後いかなる状況でもアクセスされるべきではありません

catch(...)どういうわけか、制御フローはブロックに渡され、 を削除しx、 を通り過ぎて、 に到達できると結論付けられthrow;ました*x;。他にもいくつか試しthrow std::exception("");てみましたが、同じ結果になりました。Parasoft は確かに例外を認識しており、制御フローに組み込みます。これは、例外チェックを伴うテストが他にも多数あるためです。この場合、混乱しているだけですか、それとも、このプログラムの実行で と の両方をヒットする方法が実際にdelete x;あり*x;ますか?

4

3 に答える 3

2

したがって、ツールは間違っており(以前にも言われていますが)、警告を無視したくないと思います。

一部のツールの制限を回避するためだけにコードを書き直すのはやや危険であるという@Pascalのコメントに同意します。あなたができることは、あなたが現在この問題を抱えているファイルだけに対してこの警告を無効にすることです。

次に、既存の有効なコードを書き直すように指示するツールなしで、最初に警告のないビルドがあります。

新しいコードの場合、ツールで理解できるスタイルを採用する必要があります。これは現在作業中のコードであるため、それほど問題にはなりません。したがって、警告を取り除くために少し書き直す必要がある場合は、それほど問題にはなりません。

正しいですが、既存のスタイルは理想からほど遠いです。

xauto_ptrのようにポインタを保存することをお勧めします。auto_ptrから明示的に削除しない限り、スコープ外になると、auto_ptrのコンテンツが自動的に削除されます。これは目にははるかに簡単であり、この関数がポインターの所有権を取得することもうまく文書化されています。

void foo(auto_ptr<int> x)
{
    bar();
    *x;
}

ParaSoftはこのコードで問題がないと思います。

于 2011-05-02T18:10:15.850 に答える
0

クイックアップデート:

1) 上記のルールはフロー分析ルールではありません。そうは言っても、ルール (ID MRM-31) は C++test 9.2.0 以降で改善されました。C++test には、これに対応するフロー解析ルール (ID: BD-RES-FREE) もあり、必要な処理を行う必要があります。

于 2013-06-03T22:43:43.857 に答える
0

これはばかげた提案かもしれませんが、Parasoft は、キャッチを最後まで残しておくと何と言いますか? いえ

void foo(int* x) 
  {
  try 
    {
    bar();
    *x;
    } 
  catch(...) 
    {
    delete x;
    throw;
    }      
  }

たとえば、foo のさまざまな段階でさまざまな処理でキャッチする複数の例外タイプがある場合など、ステートメントと例外のすべての組み合わせで機能しない可能性があることは理解していますが、少なくとも回避策を開始したい場合は回避策を開始できる可能性があります。警告を取り除きます。

于 2011-04-27T14:46:25.817 に答える