7

プログラムでアクセス違反を追跡しようとすると問題が発生します。これは、デストラクタが 3 回目に呼び出されたとき、つまりデストラクタが終了したように見えるときに発生します。

これを追跡するのに何時間も費やしたので、私にできることについてさらにアドバイスを探しています. newanddelete演算子を使用してクラス インスタンスを作成しています。Visual Studio の出力ウィンドウには次のように表示されます。

First-chance exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab. Unhandled exception at 0x60e3ad84 (msvcp100d.dll) in WebCollationAgent.exe: 0xC0000005: Access violation writing location 0xabababab.

それらの記憶場所に何があったかを調べるために私にできることはありますか?

コール スタック ウィンドウには次のように表示されます (古いものから新しいものへと貼り付けたので、逆の順序で表示されます)。

Program.exe!Network::`scalar deleting destructor'()  + 0x2b bytes   C++

Program.exe!std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::~basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >()  Line 754 + 0xf bytes    C++

Program.exe!std::_String_val<wchar_t,std::allocator<wchar_t> >::~_String_val<wchar_t,std::allocator<wchar_t> >()  Line 478 + 0xb bytes  C++

msvcp100d.dll!std::_Container_base12::_Orphan_all() 行 214 + 0x5 バイト C++

この情報に対する私の推測では、何らかの文字列変数が問題を引き起こしているのではないでしょうか? この情報の解釈について誰かアドバイスはありますか?

他のアドバイスも役に立ちます。よろしくお願いします。

Windows 7 でコーディングを行っており、Visual Studio 2010 Professional を使用しています。

4

3 に答える 3

4

BoundsChecker (現在は Borland DevPartner の一部)を使用する前に、メモリ バグの追跡に成功しました。HeapAgentRational Purifyなど、同様の製品も役立つ可能性があります。これらは ValGrind によく似ているように見えますが、Windows で動作します。

役立つ可能性のある 3 つのオープンソースの代替手段を次に示します。

  1. DUMA (見た目では、Windows 用に自分でビルドする必要がありますが、README にはそれを行う際の注意事項が含まれています)

  2. XMEM

これらがどのように機能するかはわかりませんが、非常に有望に聞こえます。また、すべて何らかの方法で Windows で動作するように見えます。

メモリ エラーの管理に関するこのMicrosoft ページも役立つ場合があります。また、データが最初に削除または変更された時期を確認するのに役立つメモリ ブレークポイントの設定へのリンクもあります。幸運を!

于 2012-05-08T04:05:48.173 に答える
2

Microsoft Heap Debugging を使用して、あなたのものが設計されたケースの 1 つであることを願っています。浄化はその後の次のステップです。

これは Visual Studio に組み込まれており、場合によっては役立ちます。それが機能するなら、Purify のために IBM に 2 つまたは 3 つのポケットを与えるよりも確実に優れています。

ここで情報を見つけることができます

TL;DR メインでは、これを行います

int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
// オンにする (OR) - 解放されたメモリ ブロックを
// ヒープのリンク リストを解放し、それらを解放済みとしてマークします
tmpFlag |= _CRTDBG_DELAY_FREE_MEM_DF;

// 各ヒープ操作でメモリ チェックをオンにします
tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;

// フラグの新しい状態を設定します
_CrtSetDbgFlag( tmpFlag );

_CRTDBG_CHECK_ALWAYS_DF実行が遅すぎる場合は、さまざまな場所でフラグを切り替えることができます。ただし、問題が発生する場所を把握するために、各ヒープ操作をチェックして数回実行します。

于 2012-05-08T08:11:04.937 に答える
1

ヒントを書いたブログです

http://www.atalasoft.com/cs/blogs/loufranco/archive/2007/02/06/6-_2200_Pointers_2200_-on-Debugging-Unmanaged-Code.aspx

主に行う必要があるのは、バグのあるコードがまだスタックにある間にクラッシュまたは例外を発生させることです。多くの場合、バグのあるコードが実行されて返された後、しばらくしてからアクセス違反が発生しますが、実際にはかなり後 (コンピューター時間) になる場合があります。その場合、それを理解することはほとんど不可能です。

あなたの場合、削除でフラグが立てられた問題は、ヒープが破損していることを示す強力な指標であり、C++ の 2 つの一般的な理由は、二重削除と配列の削除の混同です (delete[] を使用する必要がある場合に削除を使用するか、他の方法を使用する必要があります)。その周り)。

簡単なコードで再現できれば、上記の 2 つの問題を探します。それ以外の場合は、Microsoft Debugging Tools をダウンロードして使用gflags +hpa -i program.exeし、ヒープの破損に対する感度を高めます (エラーがより迅速に報告されます)。

于 2012-05-08T12:48:00.033 に答える