1

dll を作成しましたが、サーバー アプリケーションに関連付けられています。問題は、コマンド プロンプトからサーバーを実行すると、dll が正常に実行されることです。しかし、Visual Studio でサーバーをデバッグすると、dll が原因でサーバーがクラッシュします。その後、徹底的にデバッグしたところ、メモリの割り当て中にクラッシュしていることがわかりました。考えられること、メモリの上書き、メモリリークをすべてチェックしましたが、すべて問題ないようです。

誰もがこの種の問題に遭遇したことがあります。なぜこうなった?私もインターネットで検索しましたが、「デバッグモードではなくリリースモードでクラッシュしています」というだけです。

編集:

ウィンドウに次のメッセージが表示されます。

Windows が tcas.exe でブレークポイントをトリガーしました。これは、ヒープの破損が原因である可能性があります。これは、tcas.exe またはそれがロードした DLL のバグを示しています。これは、tcas.exe にフォーカスがあるときにユーザーが F12 を押したことが原因である可能性もあります。出力ウィンドウには、より多くの診断情報が表示される場合があります。

続行をクリックすると、問題はありません。

編集:

申し訳ありませんが、これは私が使用しているデバッグ ビルドであり、リリース ビルドではないことを忘れていました。

4

4 に答える 4

3

すべてを試し、すべての順列の組み合わせを使用し、これに多くの時間を費やした後、強制的に、関数のロジックを変更しました。そして今、ついに機能しています。それでも、私は元の問題の答えを探しています。

私も理解していなかったのは、私と同じ問題について読んだことです。ここでhttp://www.debuginfo.com/tips/userbpntdll.htmlと、ブログ、私のアプリケーションは正常に動作します。デバッグ中にクラッシュすることはありません。そして、ヒープの破損に関する詳細情報を取得できるように、最初にそれを有効にしました。このブログが、同様の問題を抱えている他の人の助けになることを願っています。

于 2013-05-16T09:37:47.987 に答える
0

コードにポインターがある場合、ポインターの 1 つを使用して未割り当てのメモリにアクセスしている可能性が高いため、デストラクタが実行されると、プログラムがクラッシュします。

少なくとも、問題が同じだったときに私が持っていたものです。

于 2013-05-10T18:44:33.393 に答える
0

私は明らかにパーティーに非常に遅れていますが、いくつかの光を当てるために、この問題に関する私の経験を共有すると思いました.

私は現在、Windows API 機能をラップする軽量のウィンドウ ライブラリを開発しています。

最上位の Window クラスの宣言には、WNDCLASSEX クラス名と対応するウィンドウのタイトルの両方を表す CHAR 配列のベース アドレスへのポインターが含まれています。この文字列はヒープに割り当てられ、たとえば Window オブジェクトが破棄されたときに NULL クラス名を登録解除しないように、常に Window のコンストラクターにコピーされます。Window のデストラクタは、CHAR バッファで delete[] も呼び出します。

問題が最初に発生したのは、1 つ以上の Window (または派生クラス) インスタンスで使用する独立したメッセージ処理関数の実装を開始したときです。ループは次のとおりです。

DWORD win_api::BeginQueueingMessages
(
    Window const *  windowList,
    UINT            length,
    INT             showCommandIndex
)
{
    BOOL processMessages    = TRUE;
    BOOL isFirstIteration   = TRUE;

    while (processMessages)
    {
        for (UINT i = 0; i < length; ++i)
        {
            Window  window  = windowList[i];
            HWND    handle  = window.getHandle();
            MSG     message = {};

            if (isFirstIteration)
            {
                ShowWindow(handle, showCommandIndex);
                UpdateWindow(handle);

                isFirstIteration = FALSE;
            }

            if (GetMessage(&message, handle, NULL, NULL))
            {
                TranslateMessage(&message);
                DispatchMessage(&message);
            }

            else
            {
                processMessages = FALSE;
            }
        }
    }

    return 0;
}

最終的に、次のコード行が原因であることが判明しました。

Window window = windowList[i];

代入演算子の使用によってトリガーされる、自動的に実装されたコピー コンストラクターを呼び出すという間違いを犯しました。したがって、左側の演算子の内部 CHAR ポインターは、新しいヒープ メモリを割り当てることなく、windowList[i] のメンバーと同じ場所を指すようになりました。

その後、プログラムの終了時に、初期化されていないメモリ ブロックに対して delete[] が呼び出され、C ランタイム例外がスローされます。

これが役立つことを願っています。

于 2016-06-23T23:30:31.767 に答える
0

あなたのプログラムには、ヒープの破損を引き起こすバグがある可能性があります。

デバッガーで実行すると、プログラムは、これらの種類のバグを見つけるのに役立つように設計された特別なバージョンのヒープを使用します。

コマンド プロンプトから実行すると、プログラム (デバッグ ビルドであっても) は、ヒープの破損を見つけるのに (まったく) 同じ助けを得るわけではありません。あなたのプログラムにはまだバグがありますが、テストの実行で問題に気付かなかったことは「幸運」です。

デバッグ ヒープを読み、それを (デバッガーで) 使用して、バグを見つけて修正します。

于 2013-05-10T16:24:36.047 に答える