2016-05-10 15 views
1

私はWin32アプリケーションをDLLに変換しようとしています。しかし、STLベクターではいくつかの問題があります。元のアプリケーションでは正常に動作しますが、DLLの「アクセス違反の読み取り場所」にエラーが発生します。ここでの.hDLLのVC++ vector :: push_back "Access Violation"

#ifdef NNETDLL_EXPORTS 
    #define NNETDLL_API __declspec(dllexport) 
    #else 
    #define NNETDLL_API __declspec(dllimport) 
    #endif 

    #include <vector> 

    using namespace std; 
    #define VECARRAY vector<double> 

    class NNETDLL_API CNNetDll 
    { 
    public: 
     CNNetDll(void); 
     virtual ~CNNetDll(); 

     int m_InputNeurons, m_HiddenNeurons, m_OutputNeurons; 

     /* Активаторы */ 
     vector<double> inputs; 
     vector<double> hidden; 
     vector<double> actual; 

     /* Вход скрытых ячеек(со смещением) */ 
     vector<VECARRAY> who; 

     /* Вход выходных ячеек(со смещением) */ 
     vector<VECARRAY> wih; 

     int InitializeNetwork(CString FileName); 
     void feedForward(); 
     void ActionNN(/*VECARRAY input_vec, VECARRAY& output_vec*/); 
     void ReadNN(CString FileName); 
    }; 

のコードです。そして、ここでの例外はアプリはベクトルを埋めようと落ちる

int CNNetDll::InitializeNetwork(CString FileName) 
{ 
    int i, hid, inp, out; 
    CFile f; 
    CString s; 
    TCHAR szDrive[200]; 
    TCHAR szDir[200]; 
    TCHAR szFile[200]; 
    TCHAR szExt[200]; 

    _wsplitpath_s(FileName, szDrive, szDir, szFile, szExt); 
    SetCurrentDirectory(szDir); 
    s = szExt; FileName = szFile + s; 

    f.Open(FileName, CFile::modeRead); 
    f.Read(&m_InputNeurons, sizeof(double)); 
    f.Read(&m_HiddenNeurons, sizeof(double)); 
    f.Read(&m_OutputNeurons, sizeof(double)); 

    for (i = 0; i < m_InputNeurons; i++) 
    { 
     inputs.push_back(0.0); // !!!!! ERROR IS HERE !!!!!! 
    } 
    for (i = 0; i < m_HiddenNeurons; i++) 
    { 
     hidden.push_back(0.0); 
    } 
    for (i = 0; i < m_OutputNeurons; i++) 
    { 
     actual.push_back(0.0); 
    } 
    for (i = 0; i < m_HiddenNeurons + 1; i++) 
    { 
     who.push_back(actual); 
    } 
    for (i = 0; i < m_InputNeurons + 1; i++) 
    { 
     wih.push_back(hidden); 
    } 
    for (hid = 0; hid < m_HiddenNeurons; hid++) 
    { 
     for (inp = 0; inp <= m_InputNeurons; inp++) 
     { 
      f.Read(&wih[inp][hid], sizeof(double)); 
     } 
    } 
    for (out = 0; out < m_OutputNeurons; out++) 
    { 
     for (hid = 0; hid <= m_HiddenNeurons; hid++) 
     { 
      f.Read(&who[hid][out], sizeof(double)); 
     } 
    } 

    f.Close(); 

    return 1; 
} 

をoccures .cppファイルのコードは、です。コールスタックの最後のステップは、この行の「xutility」ファイルにあります。

inline void _Container_base12::_Orphan_all() 
    { // orphan all iterators 
#if _ITERATOR_DEBUG_LEVEL == 2 
    if (_Myproxy != 0) 
     { // proxy allocated, drain it 
     _Lockit _Lock(_LOCK_DEBUG); 

     for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter; 
      *_Pnext != 0; *_Pnext = (*_Pnext)->_Mynextiter) // !!!!LAST OPERATION BEFORE EXCEPTION!!! 
      (*_Pnext)->_Myproxy = 0; 
     _Myproxy->_Myfirstiter = 0; 
     } 
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */ 
    } 

が正常に動作しますeverithing元のアプリケーションでは、繰り返し。また、私は、CNNetDllクラスで最初に宣言されているそのベクトルでエラーが発生することに気付きました。上のコードでは、ベクトル "入力"です。私はこの

vector<double> hidden; 
vector<double> actual; 
vector<double> inputs; 

のような宣言を変更する場合は、例外は、このコードの「隠された」ベクターで生じ

for (i = 0; i < m_InputNeurons; i++) 
{ 
    inputs.push_back(0.0); //!!!! works properly !!!!! 
} 
for (i = 0; i < m_HiddenNeurons; i++) 
{ 
    hidden.push_back(0.0); // !!! exception here !!! 
} 
for (i = 0; i < m_OutputNeurons; i++) 
{ 
    actual.push_back(0.0); 
} 

Оbjectの作成と機能の呼び出し:この問題を解決するための方法

CNNetDll nn; 
nn.InitializeNetwork(_T("M:\\Tasks\\2016\\Win8-64\\AI\\NNet\\Debug\\NN.dat")); 

????

+2

あなたはintデータ型としてm_InputNeurons、m_HiddenNeurons、m_OutputNeuronsを定義し、それにdoubleデータ型のサイズを格納しています。これにより無効なメモリアクセスが発生します。 f.Read(&m_InputNeurons、sizeof(double))を変更します。 〜f.Read(&m_InputNeurons、sizeof(int)); 3つのすべてのf.Readまたはm_InputNeuronsなどのデータ型を倍に変更します。 – MNS

+0

問題はこのような単純なことであったとは信じられませんが、今はうまくいきます。ありがとう。奇妙な.exeアプリケーションで完全に動作し、dllで失敗します。 –

+1

このようなことは、C++では生のメモリ操作で発生します。 3つの 'f.Read()'呼び出しは 'int'データ型のサイズを越えて上書きされ、' inputs'のような他のメンバ変数を破壊する可能性がありますので、 'inputs.push_back(0.0); 'アクセス違反が発生します。アクセス違反エラーは、メモリの上書きの時点で正確に発生しない可能性があります。実行の後の時点で発生する可能性があります。 – MNS

答えて

1

問題は、(intデータ型の)間違った変数定義にあり、これらの変数にdoubleデータ型のサイズを格納していました。一致する型はすべて完全に動作します。

int m_InputNeurons, m_HiddenNeurons, m_OutputNeurons; 
関連する問題