2

はじめに:古いコードをすばやくハックして修正し、__try MSVC 拡張機能を使用して、一部の ptr が正当なメモリを指しているかどうか、または *ptr がメモリ違反を引き起こすかどうかを確認しようとしています (そうであれば、この ptr の処理を​​中止します)。だから私は次のようなものを書きました:

bool checkIsPtrPointingToValidAddress(const void *ptr)
{
    __try
    {
        auto cpy = *((int*)ptr); // force mem access...
        if ( (cpy ==42) && ((rand()+rand()+rand()+rand()+ rand()) == 1))
        {
            FILE* pFile = fopen ("tempdata.dat","w"); //... by unlikely but possible action
             fputs (" ",pFile);
             fclose (pFile);
        }
        return true;
    }
    __except(1)
    {
        return false;
    }

}

メモリへのアクセスを強制する私の解決策は奇妙で醜いように見えますが、おまけとして、それが正しいかどうかはわかりません。また、プロジェクト全体で最適化を無効にすることはできないため、それはオプションではありません。また、MSDN のプラグマ オプティマイズに関するドキュメントはひどいものです。別名、"" が関数のすべての最適化を無効にするかどうかは明確ではありません。

4

3 に答える 3

10

まず第一に、そもそもそれはかなり悪い考えなので、全体のデザインを考え直した方がいいかもしれません. しかし、それに固執することを余儀なくされた場合は、次のようになります。

volatile auto copy1 = *((char*)ptr);  // using int* here could lead to aliasing violations, so better char in the general case..
volatile auto copy1 = *((char*)ptr);
if (copy1 != copy2) 
   throw std::exception("Cannot happen, but compiler cannot know this");

確かにうまくいくはずです。コンパイラは、読み取りを排除したり、それらが同一であると想定したりできないため、コードを実行する必要があります。一方、スレッドの問題やその他の興味深いシナリオがないと仮定すると、2 つの読み取りが同一であることがわかっているため、例外がスローされることはありません。

追加した

標準の規則により、揮発性オブジェクトからの読み取りまたは書き込みは、観察可能な動作 (別名、副作用) を構成するため、以下でも十分なはずです。

volatile auto copy = *((char*)ptr);

これには volatile オブジェクトへの書き込みが含まれるcopyため、最適化して取り除くことはできません。

于 2013-09-06T11:13:05.137 に答える
4

Windows API には

BOOL WINAPI IsBadReadPtr(_In_ const VOID *lp,_In_ UINT_PTR ucb);
BOOL WINAPI IsBadWritePtr(_In_ LPVOID lp, _In_ UINT_PTR ucb);

備考セクションを読む必要がありますが、ケースは単純で、これらの関数で十分かもしれません。いずれにせよ、安全でないポインタを自分で処理しようとするときに、備考セクションに役立つアドバイスがいくつかあります。

于 2013-09-16T10:25:36.180 に答える
0

ここSOでの同様の質問への回答から、次のように思われます:

  • コンパイラ依存
  • 自明でない

私が見つけた最良の情報源は、ここの質問/回答です。

ポインタがヒープ上に割り当てられたメモリを指しているかどうかを確認する

私にとって最も合理的なのは次のようです。

  1. 静的解析 (valgrind)、デバッグ、リファクタリング
  2. コンパイラにハックを使用する
  3. その回答で宣伝されている商用ソリューションを確認してください
于 2013-09-15T16:55:45.220 に答える