2016-05-10 64 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); 
    }; 

代碼而這裏的的.cpp的代碼,其中一個例外occures

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; 
} 

該應用程序瀑布試圖填補載體。在調用堆棧的最後一步是在這行「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

您已將m_InputNeurons,m_HiddenNeurons,m_OutputNeurons定義爲int數據類型,但將double數據類型的大小存儲到該數據類型中。這將導致無效的內存訪問。更改f.Read(&m_InputNeurons,sizeof(double));到f.Read(&m_InputNeurons,sizeof(int));在所有這三個f.Read或更改m_InputNeurons等數據類型加倍。 – MNS

+0

不能相信問題出現在這麼簡單的事情中,但現在它起作用了。謝謝。奇怪的是,它在.exe應用程序和DLL中完美地工作失敗。 –

+1

這種情況發生在C++中,具有原始內存操作。這三個'f.Read()'調用將會覆蓋超出'int'數據類型的大小,並且可能會破壞其他成員變量,如'inputs',所以當調用inputs.push_back(0.0);時,導致訪問衝突。訪問衝突錯誤可能不會發生在內存覆蓋的位置,它可能發生在稍後的執行階段,這是發生在這種情況下的情況。 – MNS

回答

1

問題在於錯誤的變量定義(使用int數據類型)並將雙數據類型的大小存儲到這些變量中。所有匹配類型都完美運行。

int m_InputNeurons, m_HiddenNeurons, m_OutputNeurons; 
相關問題