2

メインの最後で奇妙なアクセス違反が発生し、その原因を見つけるのに苦労しています。

アプリケーションをシャットダウンすると、次のようなアクセス違反が発生します。

xdebug

        // TEMPLATE FUNCTION _DebugHeapDelete
template<class _Ty>
    void __CLRCALL_OR_CDECL _DebugHeapDelete(_Ty *_Ptr)
    {   // delete from the debug CRT heap even if operator delete exists
    if (_Ptr != 0)
        {   // worth deleting
        _Ptr->~_Ty();
        // delete as _NORMAL_BLOCK, not _CRT_BLOCK, since we might have
        // facets allocated by normal new.
        free(_Ptr); // **ACCESS VIOLATION**
        }
    }

スタックトレース:

>   msvcp100d.dll!std::_DebugHeapDelete<void>(void * _Ptr)  Line 62 + 0xa bytes C++
    msvcp100d.dll!std::numpunct<char>::_Tidy()  Line 190 + 0xc bytes    C++
    msvcp100d.dll!std::numpunct<char>::~numpunct<char>()  Line 122  C++
    msvcp100d.dll!std::numpunct<char>::`scalar deleting destructor'()  + 0x11 bytes C++
    msvcp100d.dll!std::_DebugHeapDelete<std::locale::facet>(std::locale::facet * _Ptr)  Line 62 C++
    msvcp100d.dll!std::_Fac_node::~_Fac_node()  Line 23 + 0x11 bytes    C++
    msvcp100d.dll!std::_Fac_node::`scalar deleting destructor'()  + 0x11 bytes  C++
    msvcp100d.dll!std::_DebugHeapDelete<std::_Fac_node>(std::_Fac_node * _Ptr)  Line 62 C++
    msvcp100d.dll!_Fac_tidy()  Line 41 + 0x9 bytes  C++
    msvcp100d.dll!std::_Fac_tidy_reg_t::~_Fac_tidy_reg_t()  Line 48 + 0xe bytes C++
    msvcp100d.dll!std::`dynamic atexit destructor for '_Fac_tidy_reg''()  + 0xf bytes   C++
    msvcp100d.dll!_CRT_INIT(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 415 C
    msvcp100d.dll!__DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 526 + 0x11 bytes  C
    msvcp100d.dll!_DllMainCRTStartup(void * hDllHandle, unsigned long dwReason, void * lpreserved)  Line 476 + 0x11 bytes   C

何がこれを引き起こすのかについて誰かが何か考えを持っていますか?

キャッシュされているファセットについて何か読んだのですが、それが関連しているかどうかわかりませんか?

4

4 に答える 4

4

new演算子をオーバーライドして使用すると、私と同じ原因が発生する可能性があります。コードは次のようになります

#include "yournew" //override new declare .. 
#include "fstream" 
std::fstream f
f.open(...)

iostreamはテンプレートであるため、_Fac_nodeのnewは演算子newを使用します。ただし、終了すると、メモリプールが_Fac_tidyの前に終了し、〜_Fac_tidy()が実行されると、プログラムがクラッシュする可能性があります。

于 2011-07-13T05:02:20.067 に答える
2

メモリ破損のバグは、(明らかに)この(および他の多くの種類の)障害を引き起こす可能性があります。

これに対してvalgrind(memcheck)またはRational Purifyを使用してみましたか?おそらく問題を報告します(コードベースでこのようなチェックを実行するのが初めての場合は、他の多くの情報に埋もれている可能性があります。それでも、次の動作を示す最小限の「メイン」実装を考案する必要があります。メモリと境界チェッカーの下で実行

$ 0.02

PS。念のため、通常、メモリ破損のバグが発生します

  • 古いポインタを逆参照することによって(解放/削除後)
  • 割り当てられたバッファの終わりを超えて書き込むことによって
  • 以前のポインタを解放/削除することによって(主に所有権の追跡が悪いことの症状)
于 2011-04-05T23:05:40.880 に答える
1

MSVC10ランタイムで発生したのと同じバグが発生していると思います。私の理解では、これは、DLLがアンロードされたときにランタイムがグローバルファセットを削除し、プロセスが終了したときにそれを再度削除することが原因です。すべてを静的にリンクする場合、それは起こらないはずです。また、静的リンケージまたは共有リンケージのいずれの場合も、MSVC9では発生しません。

于 2011-10-06T15:34:59.417 に答える
1

最初の受け入れられた応答は正しいですが、それは正確に理由を示しておらず、したがってそれを修正する方法を示していません。コールスタックのリストされた部分によると、VC ++ 8(MS VS 2005)で同じ問題が発生しましたが、別のケースでは、CLRDLLがコードの同じポイントでAVを引き起こしました。

リストされた呼び出しスタックから、そのコード<xdebug>は通常msvc * .dllにコンパイルされていることがわかりますが、その時点で_Ptrすでに間違った値になっています。したがって、このポインタの下のオブジェクトをすでに解放するか、初期化されていないオブジェクトを解放するために終了フックを設定するコードがいくつかあります。

_STATIC_CPPLIBが定義されている場合、<xdebug>コードは、アプリケーションプロセスにロードされる他のモジュールにコンパイルできます。次に、これらのモジュールの1つの終了プロシージャをmsvcp100d.dll内の別の終了プロシージャの前に呼び出すことができるため、通常はファセットオブジェクトを解放できます。私の場合、_STATIC_CPPLIB定義済みで、両方のモジュール(exeとclr dll)がコンパイルされました。

VC++8,9のソリューション

「コマンドライン」セクションの最終的なコンパイラオプションで存在を確認してください/D "_STATIC_CPPLIB"。影響を受けるモジュールの定義_STATIC_CPPLIBを解除して再コンパイルすると、プログラムの終了時にAVが修正されます。

に注意してください_STATIC_CPPLIB

VC ++ 9_STATIC_CPPLIBの場合、MSDNには、次のような注記があります。

_STATIC_CPPLIBプリプロセッサ定義と /clrorコンパイラオプションの組み合わせは/clr:pureサポートされていません。

そして_STATIC_CPPLIB、より高いVSバージョンについての言及はありません。より高いVSバージョン、特にVS 10の場合、依存するコードは_STATIC_CPPLIBまだ存在していると思います。TSの場合、を含むTUまたはを含む他のヘッダー_STATIC_CPPLIBのコンパイラオプションでまだ使用されている場合、この不適切な組み合わせはAVにつながる可能性があります。<string><locale>

于 2015-12-13T07:12:22.510 に答える