2016-05-10 55 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; 
相关问题